题目链接:
http://poj.org/problem?id=1511
题目大意:
这道题目比较难理解,我读了好长时间,最后还是在队友的帮助下理解了题意,大意就是,以一为起点,求从一到其他各点的最短回路总和。
解题思路:
解决这个题目有几个容易错的,解决了离ac就不远了^_^。
1:数据范围是1<=边数<=顶点数<=1000000,所以不能用邻接矩阵,要用邻接表,用vector实现时要动态申请内存。
2:求得是起始点到其他点的最短回路和,我们可以建两个邻接表(一个正向,一个负向邻接表),对两个表分别spfa就可以了。
3:数据太大,最后结果要用__int64或者long long保存。
(这是第一次写spfa,也是第一次用vector实现邻接表,在队友的帮助下一直从大早上到现在终于解决了,可以松口气去吃饭了)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <vector> 5 #include <queue> 6 #include <iostream> 7 #include <algorithm> 8 using namespace std; 9 #define maxn 1000005 10 #define INF 2000000000 11 12 struct Egde 13 { 14 int e, w; 15 Egde(int e=0, int w=0) : e(e),w(w) {};//构造函数,初始化 16 }; 17 bool vis[maxn]; 18 __int64 dist[maxn], p; 19 vector< vector<Egde> >G[2]; 20 21 void init () 22 { 23 int i; 24 for (i=0; i<=p; i++) 25 dist[i] = INF; 26 } 27 void spfa (int x, int s); 28 29 int main () 30 { 31 int t, q; 32 scanf ("%d", &t); 33 while (t --) 34 { 35 scanf ("%d %d", &p, &q); 36 G[0].clear(); 37 G[0].resize(p+1); 38 G[1].clear(); 39 G[1].resize(p+1); 40 41 42 for (int i=0; i<q; i++) 43 { 44 int s, e, w; 45 scanf ("%d %d %d", &s, &e, &w); 46 G[0][s].push_back (Egde(e, w)); 47 G[1][e].push_back (Egde(s, w)); 48 } 49 50 __int64 sum = 0; 51 spfa (0, 1); 52 for (int i=1; i<=p; i++) 53 sum += dist[i]; 54 spfa (1, 1); 55 for (int i=1; i<=p; i++) 56 sum += dist[i]; 57 printf ("%I64d\n", sum); 58 59 } 60 return 0; 61 } 62 63 void spfa (int x, int s) 64 { 65 Egde pn; 66 queue<Egde>que; 67 memset (vis, false, sizeof(vis)); 68 init(); 69 pn.e = s, pn.w = 0; 70 dist[s] = 0; 71 que.push (pn); 72 vis[pn.e] = true; 73 while (!que.empty()) 74 { 75 pn = que.front(); 76 que.pop(); 77 vis[pn.e] = false; 78 int len = G[x][pn.e].size(); 79 for (int i=0; i<len; i++) 80 { 81 Egde p = G[x][pn.e][i]; 82 if (dist[p.e] > dist[pn.e] + p.w) 83 { 84 dist[p.e] = dist[pn.e] + p.w; 85 if (!vis[p.e]) 86 { 87 vis[p.e] = true; 88 que.push(p); 89 } 90 } 91 } 92 } 93 }
时间: 2024-10-09 02:29:56