院运会结束了,依然记得那句 "他们相信,有梦就会有飞翔"
五班加油!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;
}