POJ 1151 Invitation Cards 链式前向星+SPFA练习
题目大意:给出一个有向图,点和边都不超过1000000,求1号点到所有点的距离和+所有点到1号点的距离和。
题解:1号点到其他点的距离和直接用SPFA求,再将所有边反向,求出1号点到所有点的距离和,就是所有点到1号点的距离和,因为点非常多,故采用链式前向星存储,因这个和可能很大,注意答案要用long long 存储。
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> const int maxn=1000010,inf=1000000000; int e,to[maxn],next[maxn],begin[maxn],w[maxn]; int e1,to1[maxn],next1[maxn],begin1[maxn],w1[maxn]; int d[maxn],p[maxn],q[maxn*50]; int m,n,f,l; void add(int x,int y,int z){ to[++e]=y; next[e]=begin[x]; begin[x]=e; w[e]=z; } void add1(int x,int y,int z){ to1[++e1]=y; next1[e1]=begin1[x]; begin1[x]=e1; w1[e1]=z; } void init(){ int i,j,k,x,y,z; scanf("%d%d",&n,&m); e=0;e1=0; for(i=1;i<=n;i++)begin[i]=0; for(i=1;i<=n;i++)begin1[i]=0; for(i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add1(y,x,z); } } int main(){ int i,j,k,t; long long ans; scanf("%d",&t); while(t--){ init(); for(i=1;i<=n;i++){ d[i]=inf; p[i]=0; } f=0;l=1; d[1]=0;q[1]=1;p[1]=1; while(f<l){ f++; k=q[f];p[k]=0; for(i=begin[k]; i ; i=next[i]) if(d[to[i]]>d[k]+w[i]){ d[to[i]]=d[k]+w[i]; if(!p[to[i]]){ q[++l]=to[i]; p[to[i]]=1; } } } ans=0; for(i=1;i<=n;i++)ans+=d[i]; for(i=1;i<=n;i++){ d[i]=inf; p[i]=0; } f=0;l=1; d[1]=0;q[1]=1;p[1]=1; while(f<l){ f++; k=q[f];p[k]=0; for(i=begin1[k]; i ; i=next1[i]) if(d[to1[i]]>d[k]+w1[i]){ d[to1[i]]=d[k]+w1[i]; if(!p[to1[i]]){ q[++l]=to1[i]; p[to1[i]]=1; } } } for(i=1;i<=n;i++)ans+=d[i]; printf("%I64d\n",ans); } return 0; }