• 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
    ",ans);        
            
        }    
        return 0;    
    }
    


  • 相关阅读:
    21-while里的break简单用法
    20-使用while循环求从1累加至100的值
    19-random猜数
    18-random猜数,直到正确。
    17-简化后的石头剪刀布
    16-if实现石头剪刀布
    生成随机数
    转换数字的进制(Integer、Long)
    数字的舍入
    格式化数字
  • 原文地址:https://www.cnblogs.com/cnyali/p/4163893.html
Copyright © 2020-2023  润新知