POJ1511 Invitation Cards(多源单汇最短路)
边取反,从汇点跑单源最短路即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 1111111 7 #define MAXM 1111111 8 9 inline void in(int &ret){ 10 char c; ret=0; 11 while(c=getchar(),c<'0'||c>'9'); 12 while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar(); 13 } 14 void out(long long x){ 15 if(x>9) out(x/10); 16 putchar(x%10+'0'); 17 } 18 19 struct Edge{ 20 int v,cost,next; 21 }edge[MAXM<<1]; 22 int head[MAXN],rhead[MAXN],NE; 23 void addEdge(int a,int b,int c){ 24 edge[NE].v=b; edge[NE].cost=c; edge[NE].next=head[a]; 25 head[a]=NE++; 26 edge[NE].v=a; edge[NE].cost=c; edge[NE].next=rhead[b]; 27 rhead[b]=NE++; 28 } 29 30 int n,m; 31 int d[MAXN]; 32 bool vis[MAXN]; 33 void SPFA(){ 34 memset(d,127,sizeof(d)); 35 d[1]=0; 36 memset(vis,0,sizeof(vis)); 37 vis[1]=1; 38 queue<int> que; 39 que.push(1); 40 while(!que.empty()){ 41 int u=que.front(); que.pop(); 42 for(int i=head[u];i !=-1; i=edge[i].next){ 43 int v=edge[i].v; 44 if(d[v]>d[u]+edge[i].cost){ 45 d[v]=d[u]+edge[i].cost; 46 if(!vis[v]){ 47 vis[v]=1; 48 que.push(v); 49 } 50 } 51 } 52 vis[u]=0; 53 } 54 } 55 void rSPFA(){ 56 memset(d,127,sizeof(d)); 57 d[1]=0; 58 memset(vis,0,sizeof(vis)); 59 vis[1]=1; 60 queue<int> que; 61 que.push(1); 62 while(!que.empty()){ 63 int u=que.front(); que.pop(); 64 for(int i=rhead[u]; i!=-1; i=edge[i].next){ 65 int v=edge[i].v; 66 if(d[v]>d[u]+edge[i].cost){ 67 d[v]=d[u]+edge[i].cost; 68 if(!vis[v]){ 69 vis[v]=1; 70 que.push(v); 71 } 72 } 73 } 74 vis[u]=0; 75 } 76 } 77 78 int main(){ 79 int t,a,b,c; 80 in(t); 81 while(t--){ 82 NE=0; 83 memset(head,-1,sizeof(head)); 84 memset(rhead,-1,sizeof(rhead)); 85 in(n); in(m); 86 while(m--){ 87 in(a); in(b); in(c); 88 addEdge(a,b,c); 89 } 90 long long res=0; 91 SPFA(); 92 for(int i=1; i<=n; ++i) res+=d[i]; 93 rSPFA(); 94 for(int i=1; i<=n; ++i) res+=d[i]; 95 out(res); putchar('\n'); 96 } 97 return 0; 98 }