题目链接:https://vjudge.net/problem/POJ-1511
一道简单的最短路变形,正向图和反向图各搜一遍加起来就OK,要用spfa或者dijkstra+heap
但是数据量比较大,所以卡了挺久,一是范围要开long long,不然会WA
二是以前习惯了用vector做邻接表,但这道题一直卡着超时,用数组做了邻接表才AC
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int N=1000000+10;
const long long inf=1e10+10;
struct edge
{
int to;
int c;
int next;
};
long long vis[N],vis0[N];
bool d[N];
edge g[N],g0[N];
int head[N],head0[N];
int cnt,cnt0;
int t,n,m;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int a,b,c;
memset(vis,inf,sizeof(vis));
memset(vis0,inf,sizeof(vis0));
memset(head,-1,sizeof(head));
memset(head0,-1,sizeof(head0));
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
g[i].to=b;
g[i].c=c;
g[i].next=head[a];
head[a]=i;
g0[i].to=a;
g0[i].c=c;
g0[i].next=head0[b];
head0[b]=i;
}
queue<int> q;
memset(d,false,sizeof(d));
q.push(1);
vis[1]=0;
while(!q.empty())
{
int pos=q.front();q.pop();
d[pos]=false;
for(int i=head[pos];i!=-1;i=g[i].next)
{
int v=g[i].to;
int c=g[i].c;
if(vis[v]>vis[pos]+c)
{
vis[v]=vis[pos]+c;
if(!d[v])
q.push(v);
d[v]=true;
}
}
}
q.push(1);
memset(d,false,sizeof(d));
vis0[1]=0;
while(!q.empty())
{
int pos=q.front();q.pop();
d[pos]=false;
for(int i=head0[pos];i!=-1;i=g0[i].next)
{
int v=g0[i].to;
int c=g0[i].c;
if(vis0[v]>vis0[pos]+c)
{
vis0[v]=vis0[pos]+c;
if(!d[v])
q.push(v);
d[v]=true;
}
}
}
long long ans=0;
for(int i=1;i<=n;i++)
ans+=vis[i]+vis0[i];
printf("%lld\n",ans);
}
return 0;
}