zoj 2008 单源最短路 SPFA
/* 题意:一个有向带权图,求1到所有点的最小权值,再求所有点到1的最小权值 题解:典型单源最短路,用SPFA实现,要求1分别为起点和终点时的最小权值和, 当1为终点时只需将图建立一个反向图,即可将终点当作起点计算 */ #include <iostream> #include <vector> #include <queue> #include <cstring> #define Max 1000000001 using namespace std; typedef struct { int pr; int to; }node; int p; vector<node> G[1000005],G0[1000005]; int dist[1000005]; bool vis[1000005]; void spfa(int start) { for(int i=0; i<=p; i++) { dist[i] = Max; vis[i] = false; } queue<int> Q; dist[start] = 0; vis[start] = true; Q.push(start); while (!Q.empty()) { int t = Q.front(); Q.pop(); for(int i=0; i<G[t].size(); i++) { if (dist[t]+G[t][i].pr < dist[G[t][i].to]) { dist[G[t][i].to] = dist[t] + G[t][i].pr; if (!vis[G[t][i].to]) { Q.push(G[t][i].to); vis[G[t][i].to] = true; } } } vis[t] = false; } } void spfa0(int start) { for(int i=0; i<=p; i++) { dist[i] = Max; vis[i] = false; } queue<int> Q; dist[start] = 0; vis[start] = true; Q.push(start); while (!Q.empty()) { int t = Q.front(); Q.pop(); for(int i=0; i<G0[t].size(); i++) { if (dist[t]+G0[t][i].pr < dist[G0[t][i].to]) { dist[G0[t][i].to] = dist[t] + G0[t][i].pr; if (!vis[G0[t][i].to]) { Q.push(G0[t][i].to); vis[G0[t][i].to] = true; } } } vis[t] = false; } } int main(void) { int n,q,fr,to,price; cin >> n; while (n--) { cin >> p >> q; for(int i=0; i<=p; i++) { G[i].clear(); G0[i].clear(); } while (q--) { cin >> fr >> to >> price; node tmp; tmp.to = to; tmp.pr = price; G[fr].push_back(tmp); tmp.to = fr; G0[to].push_back(tmp); } spfa(1); int sum = 0; for(int i=1; i<=p; i++) sum += dist[i]; spfa0(1); for(int i=1; i<=p; i++) sum += dist[i]; cout << sum << endl; } return 0; }