题目大意:
计算从 1 点 到 其他所有点的 往返距离之和, 因为是 有向图, 所以我们需要将图反存 一次, 然后求两次单源最短路, 结果就出来了。
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> using namespace std; #define INF 0xffffffff #define maxn 1000005 struct Edge { int w, e; }; int UseCount[maxn], m ,n; bool Use[maxn]; long long dist[2][maxn]; vector<vector<Edge> > G[2]; void Init() { G[0].clear(); G[1].clear(); G[0].resize(n+1); G[1].resize(n+1); for(int i=1; i<=n; i++) { dist[1][i] = dist[0][i] = INF, Use[i] = false; } } long long Spfa(int k) { Edge P, Pn; P.w = 0, P.e = 1; dist[k][1] = 0; queue<Edge>Q; Q.push(P); while( !Q.empty() ) { P = Q.front(); Q.pop(); Use[P.e] = false; int len = G[k][P.e].size(); for(int i=0; i<len; i++) { Pn = G[k][P.e][i]; if(dist[k][Pn.e] > dist[k][P.e] + Pn.w) { dist[k][Pn.e] = dist[k][P.e] + Pn.w; if( !Use[Pn.e] ) { Q.push(Pn); Use[Pn.e] = true; } } } } long long sum = 0; for(int i=1; i<=n; i++) sum += dist[k][i]; return sum; } int main() { int T; Edge P; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); Init(); for(int i=0; i<m; i++) { int a, b, c; scanf("%d%d%d",&a,&b,&c); P.e = b, P.w = c; G[0][a].push_back(P); P.e = a; G[1][b].push_back(P); } long long sum = 0; sum += Spfa(0); sum += Spfa(1); printf("%I64d ",sum); } return 0; }