很长时间没写了,现在写起最短路来有些生疏了。总体而言这题还是挺简单的,思路如下:去的时候求出起点到每个车站的最短距离,用SPFA来求。回来的时候求出每个车站到起点的最短距离,因为每条路线都是单向的,所以显然两种结果是不一样的,但可以用同一个思路来求,就是回来的时候和去的时候一样,只不过把从b到a,换成从a到b,那么就和出发的时候一样,也可以用SPFA来求。
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1000005;
const long long inf=2000000000000000;
int head1[N],head2[N];
long long dist1[N],dist2[N];//这里要用long long ,一开始没用错了
bool visited[N];
struct Edge
{
int v,w,next;
}edge1[N],edge2[N];
int top1,top2;
void add_edge(Edge edge[],int head[],int &top,int v,int u,int w)//这里top注意要用引用,一开始没用,结果每次top的值都是1,不会变化
{
edge[top].v=v,edge[top].w=w;
edge[top].next=head[u];
head[u]=top++;
}
void spfa(int head[],Edge edge[],long long dist[],int n)
{
for(int i=1;i<=n;i++)
{
visited[i]=false;
dist[i]=inf;
}
queue<int> q;
q.push(1);
visited[1]=true;
dist[1]=0;
while(!q.empty())
{
int t=q.front();
q.pop();
visited[t]=false;
for(int i=head[t];i!=-1;i=edge[i].next)
{
long long len=dist[t]+edge[i].w;
int v=edge[i].v;
if(len<dist[v])
{
dist[v]=len;
if(visited[v]==false)
{
visited[v]=true;
q.push(v);
}
}
}
}
}
int main()
{
int t,p,q,a,b,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&p,&q);
for(int i=1;i<=N;i++)
{
head1[i]=-1;
head2[i]=-1;
}
top1=top2=1;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&a,&b,&c);
add_edge(edge1,head1,top1,a,b,c);//把路径顺序变换一下,好用两次SPFA
add_edge(edge2,head2,top2,b,a,c);
}
spfa(head1,edge1,dist1,p);
spfa(head2,edge2,dist2,p);
long long ans=0;
for(int i=1;i<=p;i++)
{
long long d=dist1[i]+dist2[i];
ans+=d;
}
printf("%lld\n",ans);
}
return 0;
}