单元最短路问题,正向建一次图,反向建一次图,把两次spfa()的结果相加即可。
#include<stdio.h>
#include<string.h>
struct Node{
long long start;
long long end;
long long len;
long long next;
}node[1000010],node1[1000010];
long long dist[1000010],vis[1000010],head[1000010],q[4000020],head1[1000010];
long long n,t,tot,front,rear;
void spfa()
{
long long u,v;
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
dist[i]=1000000010;
vis[1]=1;
dist[1]=0;
front=rear=0;
q[front++]=1;
while(front!=rear)
{
u=q[rear++];
vis[u]=0;
for(int i=head[u];i!=-1;i=node[i].next)
{
v=node[i].end;
if(dist[v]>dist[u]+node[i].len)
{
dist[v]=dist[u]+node[i].len;
if(vis[v]==0)
{
q[front++]=v;
vis[v]=1;
}
}
}
}
}
void spfa1()
{
long long u,v;
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)
dist[i]=1000000010;
vis[1]=1;
dist[1]=0;
front=rear=0;
q[front++]=1;
while(front!=rear)
{
u=q[rear++];
vis[u]=0;
for(int i=head1[u];i!=-1;i=node1[i].next)
{
v=node1[i].start;
if(dist[v]>dist[u]+node1[i].len)
{
dist[v]=dist[u]+node1[i].len;
if(vis[v]==0)
{
q[front++]=v;
vis[v]=1;
}
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&tot);
memset(head,-1,sizeof(head));
memset(head1,-1,sizeof(head1));
for(int i=1,j=1;i<=tot,j<=tot;i++,j++)
{
scanf("%d%d%d",&node[i].start,&node[i].end,&node[i].len);
node1[j].start=node[i].start;
node1[j].end=node[i].end;
node1[j].len=node[i].len;
node[i].next=head[node[i].start];
head[node[i].start]=i;
node1[j].next=head1[node1[j].end];
head1[node1[j].end]=j;
}
spfa();
long long sum1=0;
for(int i=1;i<=n;i++)
{
sum1+=dist[i];
//printf("%d!\n",dist[i]);
}
spfa1();
long long sum2=0;
for(int i=1;i<=n;i++)
{
sum2+=dist[i];
//printf("%d!!\n",dist[i]);
}
printf("%I64d\n",sum1+sum2);
}
return 0;
}