ZOJ--2008(最短路)
2015-01-06 10:50:06
思路:最短路简单题,首先跑一遍起点1到所有点的最短路,spfa。然后将所有边反向,再跑一遍,这样就求出了其余N-1个点到起点1的最短路。把所有距离加起来就是答案。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 typedef pair<int,int> pii; 20 const int INF = (1 << 30) - 1; 21 const int maxn = 1000010; 22 23 int T,N,M,sum1,sum2; 24 int first[maxn],next[maxn],ecnt; 25 int inq[maxn],dis[maxn]; 26 27 struct edge{ 28 int u,v,cost; 29 }e[maxn]; 30 31 void Add_edge(int u,int v,int c){ 32 next[++ecnt] = first[u]; 33 e[ecnt].u = u; 34 e[ecnt].v = v; 35 e[ecnt].cost = c; 36 first[u] = ecnt; 37 } 38 39 void Spfa(int s){ 40 queue<int> Q; 41 memset(inq,0,sizeof(inq)); 42 fill(dis + 1,dis + N + 1,INF); 43 dis[s] = 0; 44 inq[s] = 1; 45 Q.push(s); 46 while(!Q.empty()){ 47 int x = Q.front(); Q.pop(); 48 inq[x] = 0; 49 for(int i = first[x]; i != -1; i = next[i]){ 50 int v = e[i].v; 51 if(dis[v] > dis[x] + e[i].cost){ 52 dis[v] = dis[x] + e[i].cost; 53 if(inq[v] == 0){ 54 inq[v] = 1; 55 Q.push(v); 56 } 57 } 58 } 59 } 60 } 61 62 int main(){ 63 int a,b,c; 64 scanf("%d",&T); 65 while(T--){ 66 memset(first,-1,sizeof(first)); 67 ecnt = 0; 68 scanf("%d%d",&N,&M); 69 for(int i = 1; i <= M; ++i){ 70 scanf("%d%d%d",&a,&b,&c); 71 Add_edge(a,b,c); 72 } 73 Spfa(1); 74 sum1 = 0; 75 for(int i = 1; i <= N; ++i) sum1 += dis[i]; 76 int sz = ecnt; 77 memset(first,-1,sizeof(first)); 78 ecnt = 0; 79 for(int i = 1; i <= sz; ++i){ 80 Add_edge(e[i].v,e[i].u,e[i].cost); 81 } 82 Spfa(1); 83 sum2 = 0; 84 for(int i = 1; i <= N; ++i) sum2 += dis[i]; 85 printf("%d\n",sum1 + sum2); 86 } 87 return 0; 88 }