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;    
}


posted @ 2014-12-14 15:16  cnyali  阅读(159)  评论(0编辑  收藏  举报