一道很简单的图论题。题目意思很简单:有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; }