题目链接:Invitation Cards
题意:
给出一张有向图,现在要求从1到其他所有的结点的最小路径和与从所有其他结点到1的最小路径和之和。
题解:
求最小路径可以用SPFA来求解。从1到其他结点的正向跑一遍SPFA就可以求出来了,要求其他结点到1的最小路径则可以反向建图跑一边SPFA。但是这里面很奇怪的是,如果正向和反向建图开两个vector就会TLE,开一个就不会TLE了。@。@?
1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 using namespace std; 8 typedef pair<int,int> P; 9 struct edge{ 10 int u,v,val; 11 }; 12 13 const int MAX_N = 1e6+9; 14 const int INF = 1e9+7; 15 vector<P> vec[MAX_N]; 16 vector<P> vec2[MAX_N]; 17 int res[MAX_N]; 18 int vis[MAX_N]; 19 edge tran[MAX_N]; 20 queue<int> que; 21 int N,M,T,a,b,x; 22 long long ans; 23 void init() 24 { 25 for(int i=0;i<=N;i++) 26 { 27 vec[i].clear(); 28 vec2[i].clear(); 29 } 30 while(!que.empty()) que.pop(); 31 ans = 0; 32 } 33 void spfa(int z) 34 { 35 while(!que.empty()) que.pop(); 36 for(int i=0;i<=N;i++) 37 { 38 res[i] = INF; 39 vis[i] = 0; 40 } 41 res[z] = 0; 42 vis[z] = 1; 43 que.push(z); 44 while(!que.empty()) 45 { 46 int t = que.front(); 47 que.pop(); 48 vis[t] = 0; 49 for(int i=0;i<vec[t].size();i++) 50 { 51 P temp = vec[t][i]; 52 53 if(res[temp.first] > res[t] + temp.second) 54 { 55 res[temp.first] = res[t] + temp.second; 56 if(vis[temp.first] == 0) 57 { 58 vis[temp.first] = 1; 59 que.push(temp.first); 60 } 61 } 62 63 } 64 } 65 for(int i=2;i<=N;i++) ans += res[i]; 66 } 67 68 int main() 69 { 70 cin>>T; 71 while(T--) 72 { 73 scanf("%d%d",&N,&M); 74 init(); 75 for(int i=0;i<M;i++) 76 { 77 scanf("%d%d%d",&tran[i].u,&tran[i].v,&tran[i].val); 78 vec[tran[i].u].push_back(P(tran[i].v,tran[i].val)); 79 } 80 spfa(1); 81 for(int i=0;i<=N;i++) vec[i].clear(); 82 for(int i=0;i<M;i++) 83 { 84 vec[tran[i].v].push_back(P(tran[i].u,tran[i].val)); 85 } 86 spfa(1); 87 printf("%lld ",ans); 88 } 89 return 0; 90 }