http://acm.hdu.edu.cn/showproblem.php?pid=1535
这道题两遍spfa,第一遍sfpa之后,重新建图,所有的边逆向建边,再一次spfa就可以了。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <queue> 5 #include <algorithm> 6 #define maxn 1000001 7 using namespace std; 8 const int inf=1000000000; 9 10 long long dis1[maxn]; 11 long long dis2[maxn]; 12 int e1,head[maxn],e2; 13 bool vis[maxn]; 14 int cnt[maxn]; 15 int P,Q,s,e,n; 16 long long w; 17 struct node 18 { 19 int u,v,next; 20 long long w; 21 }p[maxn],p1[maxn]; 22 23 void add(int u,int v,long long w) 24 { 25 p[e1].u=u; 26 p[e1].v=v; 27 p[e1].w=w; 28 p[e1].next=head[u]; 29 head[u]=e1++; 30 } 31 32 bool spfa(int src,long long dis[]) 33 { 34 queue<int>q; 35 memset(cnt,0,sizeof(cnt)); 36 memset(vis,false,sizeof(vis)); 37 for(int i=1; i<=n; i++) dis[i]=inf; 38 dis[src]=0; 39 vis[src]=true; 40 q.push(src); 41 while(!q.empty()) 42 { 43 int u=q.front(); q.pop(); 44 vis[u]=false; 45 for(int i=head[u]; i!=-1; i=p[i].next) 46 { 47 int vv=p[i].v; 48 long long ww=p[i].w; 49 if(dis[vv]>dis[u]+ww) 50 { 51 dis[vv]=dis[u]+ww; 52 if((++cnt[vv])>n) return false; 53 if(!vis[vv]) 54 { 55 q.push(vv); 56 vis[vv]=true; 57 } 58 } 59 } 60 } 61 return true; 62 } 63 int main() 64 { 65 int t; 66 scanf("%d",&t); 67 while(t--) 68 { 69 e1=0; 70 memset(head,-1,sizeof(head)); 71 scanf("%d%d",&P,&Q); 72 for(int i=0; i<Q; i++) 73 { 74 cin>>p1[i].u>>p1[i].v>>p1[i].w; 75 add(p1[i].u,p1[i].v,p1[i].w); 76 } 77 n=P; 78 spfa(1,dis1); 79 long long sum=0; 80 e1=0; 81 memset(head,-1,sizeof(head)); 82 for(int i=0; i<Q; i++) 83 { 84 add(p1[i].v,p1[i].u,p1[i].w); 85 } 86 spfa(1,dis2); 87 for(int i=2; i<=n; i++) 88 { 89 sum+=(dis1[i]+dis2[i]); 90 } 91 cout<<sum<<endl; 92 } 93 return 0; 94 }