标签:Node pp 洛谷 int 题解 Edge que P5340 maxn
题目链接:https://www.luogu.com.cn/problem/P5340
解题思路:
拆点/分层图最短路。
每个点 \(u\) 及到达点 \(u\) 是所吃汉堡与所喝可乐数量之差 \(p\) 对应一个二元组 \((u,p)\)。对二元组求最短路。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10100;
struct Edge {
int v, w;
Edge() {}
Edge(int _v, int _w) { v = _v; w = _w; }
};
vector<Edge> g[maxn];
int dis[maxn][21], T, n, m, k, a[maxn], s, t;
bool vis[maxn][21];
struct Node {
int u, p, w;
Node() {}
Node(int _u, int _p, int _w) { u = _u; p = _p; w = _w; }
bool operator < (const Node & b) const {
return w > b.w;
}
};
priority_queue<Node> que;
int main() {
ios::sync_with_stdio(0);
cin >> T;
while (T --) {
cin >> n >> m >> k;
for (int i = 1; i <= n; i ++) {
for (int j = 0; j <= 2*k; j ++) {
dis[i][j] = -1;
vis[i][j] = false;
}
}
for (int i = 1; i <= n; i ++) {
cin >> a[i];
g[i].clear();
}
while (m --) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back(Edge(v, w));
g[v].push_back(Edge(u, w));
}
cin >> s >> t;
dis[s][k+(a[s]==1 ? 1 : -1)] = 0;
que.push(Node(s, (a[s]==1 ? 1 : -1), 0));
while (!que.empty()) {
Node nd = que.top();
que.pop();
int u = nd.u, p = nd.p, w = nd.w;
if (vis[u][k+p]) continue;
vis[u][k+p] = true;
for (auto e : g[u]) {
int v = e.v;
int pp = p + (a[v]==1 ? 1 : -1);
if (pp >= -k && pp <= k && (dis[v][k+pp] == -1 || dis[v][k+pp] > w + e.w)) {
dis[v][k+pp] = w + e.w;
que.push(Node(v, pp, w+e.w));
}
}
}
int ans = -1;
for (int i = -k; i <= k; i ++) {
if (dis[t][k+i] != -1 && (ans == -1 || ans > dis[t][k+i]))
ans = dis[t][k+i];
}
cout << ans << endl;
}
return 0;
}
标签:Node,pp,洛谷,int,题解,Edge,que,P5340,maxn 来源: https://www.cnblogs.com/quanjun/p/15562997.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。