院运会结束了,依然记得那句 "他们相信,有梦就会有飞翔"
五班加油!Justey加油!!xsbailong加油!!!
有梦就会有飞翔!!!!
/* zoj_2008 最短路 依旧用dijk实现的,看网上很多人都spfa,可是我还没碰过spfa。。 这题做的也不顺利。 Process: 1.首先反应居然是floyd,然后一看p、q都达到1000000了。。肯定MLE的 2.然后发现两次dijk是可以实现的,第二次则是单源最短路径的变形--单终点最短路径 对所有边求发现边再dijk即可。实现起来很容易~ 3.然后懒得学邻接表,拿邻接矩阵去碰碰运气,果断MLE。。 4.只得换邻接表,第一次用邻接表写dijk。。ND的不顺利,本以为随便改下就好,结果 wa了数次。。终于发现写错。。将dijk改了下,终于算是过了。。虽然效率依旧很低。。 有时间看下spfa 收获:1.熟悉 单源最短路径的变形--单终点最短路径 2.邻接表写dijk */ #include <iostream> #include <cstdio> #include <vector> #include <string.h> #include <limits.h> #define N 1000010 #define LL long long using namespace std; int flag[N],dist[N]; LL sum; struct node { int to,val; node( int a=0,int b=0 ) { to=a; val=b; } }; vector <node> map[N][2]; void inint() { int i,j; for( i=0;i<N;i++ ) for( j=0;j<2;j++ ) map[i][j].clear(); } void dijkstra( int sta,int n,int co ) { int i,j,k,mini,mark,temp; memset( flag,0,sizeof(flag) ); memset( dist,0,sizeof(dist) ); flag[sta]=1; for( i=0;i<=n;i++ ) { mini=INT_MAX; for( k=0;k<map[sta][co].size();k++ ) { temp=map[sta][co][k].to; if( !flag[temp] ) { if( dist[temp]==0 ) dist[temp]=dist[sta]+map[sta][co][k].val; else if( dist[temp]>dist[sta]+map[sta][co][k].val ) dist[temp]=dist[sta]+map[sta][co][k].val; } } for( j=1;j<=n;j++ ) { if( !flag[j] ) { if( mini>dist[j] && dist[j]!=0 ) { mini=dist[j]; mark=j; } } } if( mini==INT_MAX ) break; sta=mark; flag[sta]=1; } for( i=2;i<=n;i++ ) sum+=dist[i]; } int main() { int n,p,q,i; int a,b,v; scanf( "%d",&n ); while( n-- ) { inint(); scanf( "%d%d",&p,&q ); while( q-- ) { scanf( "%d%d%d",&a,&b,&v ); map[a][0].push_back( node( b,v ) ); map[b][1].push_back( node( a,v ) ); } sum=0; dijkstra( 1,p,0 ); dijkstra( 1,p,1 ); printf( "%lld\n",sum ); } return 0; }