标签:
Description:
Input:
Output:
Sample Input:
2 2 2 1 2 13 2 1 33 4 6 1 2 10 2 1 60 1 3 20 3 4 10 2 4 5 4 1 50
Sample Output:
46 210
题意:一些学生被雇佣来分发请柬,他们每次从中心站出发到达其他的站分发请柬,现在要计算一天下来给他们的工资最少为多少,(从a站到b站给的工资和b站到a站可能是不一样的,但是最终每个人都是要回到中心站的,此题中中心站标号是1),和POJ 3268 Silver Cow Party相似,都是进行两次spfa算法,不同的是这次的数据较大,用邻接表更好。
#include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; const int N=1000010; const int INF=0x3f3f3f3f; int d1[N], d2[N], vis[N], n, head[N], k; struct node { int v, flow, next; }no[N]; struct mode { int a, b, c; }mo[N]; void Init(int d[]) { int i; for (i = 1; i <= n; i++) { d[i] = INF; vis[i] = 0; head[i] = -1; } k = 0; } void Add(int a, int b, int c) { no[k].v = b; no[k].flow = c; no[k].next = head[a]; head[a] = k++; } void Spfa(int d[]) { int v, i, u; queue<int>Q; Q.push(1); d[1] = 0; while (!Q.empty()) { v = Q.front(); Q.pop(); for (i = head[v]; i != -1; i = no[i].next) { u = no[i].v; if (d[u] > d[v]+no[i].flow) { d[u] = d[v]+no[i].flow; if (!vis[u]) { Q.push(u); vis[u] = 1; } } } vis[v] = 0; } } int main () { int T, m, i; long long ans; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); Init(d1); ans = 0; for (i = 1; i <= m; i++) { scanf("%d%d%d", &mo[i].a, &mo[i].b, &mo[i].c); Add(mo[i].a, mo[i].b, mo[i].c); ///先顺方向存入,计算1到其他点的最短路径 } Spfa(d1); Init(d2); ///再次初始化后反向存入,计算1到其他点的最短路径 for (i = 1; i <= m; i++) Add(mo[i].b, mo[i].a, mo[i].c); Spfa(d2); for (i = 1; i <= n; i++) ans += d1[i]+d2[i]; printf("%lld\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4813912.html