这个题其实是一个求最短路的问题,比较特殊的一点是汽车在返回的时候是空车返回的,那么我们就求两次最短路,第一次以节点1为起始点,第二次以节点N为起始点,将二者的结果相加就是结果。
//spaf是Bella_man算法的一个优化算法,要比Bella_man快很多
#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct node{
int v,next;
long w;
};
node e[2000010];
long dis[2000010];
int P,Q,cas;
int all[2000010];
bool inqu[2000010];
queue<int>q;
int spaf(int s ){
int i,now;
q.push(s);
dis[s]=0;
inqu[s]=1;
while(!q.empty()){
now=q.front();
q.pop();
inqu[now]=0;
for(i=all[now];i!=-1;i=e[i].next)
{
if(dis[now]+e[i].w<dis[e[i].v])
{
dis[e[i].v]=dis[now]+e[i].w;
if(!inqu[e[i].v]){
q.push(e[i].v);
inqu[e[i].v]=1;
}
}
}
}
return 0;
}
int main(){
int s,t,w,i,num;
scanf("%d",&cas);
while(cas--){
memset(inqu,0,sizeof(inqu));
memset(all,-1,sizeof(all));
scanf("%d%d",&P,&Q);
for(i=1;i<=2*P;i++)
dis[i]=1000000000;
num=0;
while(Q--){
scanf("%d%d%d",&s,&t,&w);
e[num].next=all[s];//这里用的是向前星存储结构,并将反向路径上的节点扩展为N+1,N+2。。。
all[s]=num;
e[num].v=t;
e[num++].w=w;
e[num].next=all[P+t];
all[P+t]=num;
e[num].v=P+s;
e[num++].w=w;
}
spaf(1);
spaf(P+1);
long ans=0;
for(i=1;i<=2*P;i++)
ans+=dis[i];
printf("%I64d\n",ans);
}
return 0;
}