POJ 1511 Invitation Cards

       一道很简单的图论题。题目意思很简单:有n个公交车站,同时有n个同学,要派每个同学到n个站去发邀请涵,所有同学都是在起点CSS坐公交去自己的站点,但是公交车是单向行驶的,到了晚上所有的同学都要坐公交回到起点CSS。问最小的费用是多少。这题一眼就可以看出是最短路问题,题目保证图相互连通的。建图很简单,单向边,建一个正向图,建一个反向图,两次从源点1进行一次SPFA。我原来超时了两次,让我知道c语言输入输出的强大,这道题数据很大,边有1000000.我原来用cin,cout.8s都超时,结果我设置了标志位,还吵,换成scanf,1.9s.让喜欢c++的情何以堪!

代码:

#include<iostream>
#define maxn 1000005
using namespace std;
struct Edge
{
       int v,w,next;
} e[maxn*2],re[maxn*2];
int dist[maxn],head[maxn],que[maxn*2];
bool mark[maxn];
int n,size,rhead[maxn];
void AddEdge(int a,int b,int c)
{
     e[size].v=b;  re[size].v=a;
     e[size].w=c;  re[size].w=c;
     e[size].next=head[a]; re[size].next=rhead[b];
     head[a]=size;  rhead[b]=size++;
}
__int64 SPFA(Edge a[],int h[])
{
    int first,rear,u,v,i;
    first=rear=0;
    que[rear++]=1;
    memset(dist,0x7f,sizeof(dist));
    memset(mark,false,sizeof(mark));
    dist[1]=0; mark[1]=true;
    while( first!=rear){
           u=que[first++]; mark[u]=false;
           for( i=h[u]; i!=-1; i=a[i].next){
                v=a[i].v;
                if( dist[v]>dist[u]+a[i].w){
                    dist[v]=dist[u]+a[i].w;
                    if(!mark[v]) {
                      que[rear++]=v;
                      mark[v]=true;
                    }   
                }
           }
    }
    __int64 ans=0;
    for(i=1;i<=n;i++)
       ans+=dist[i];
    return ans;       
}
int main()
{
    int t,m,a,b,c;
    scanf("%d",&t);
    while( t--){
           memset(head,-1,sizeof(head));
           memset(rhead,-1,sizeof(rhead));
           memset(e,0,sizeof(e));
           memset(re,0,sizeof(re));
           cin>>n>>m;
           size=0;
           while( m--){
                  scanf("%d%d%d",&a,&b,&c);
                  AddEdge(a,b,c);
           }
           __int64 ret=0;
           ret=SPFA(e,head);
           ret+=SPFA(re,rhead);  
           printf("%I64d\n",ret);    
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值