http://acm.hdu.edu.cn/showproblem.php?pid=1535
spfa,根据题意需要将单向图正向算一遍从1到其余点的最短距离再反向来一遍,难在相处题意。
#include<bits/stdc++.h>
using namespace std;
int u[11111111];
int v[11111111];
int w[11111111];
int first[11111111];
int nex[11111111];
int dis[11111111];
int vis[11111111]; int c,p;
void spfa(int st,int zf)
{
int i;
for(i=0;i<=c;i++)
dis[i]=1111111111;
dis[st]=0;
for(i = 0;i<=c;i++)
vis[i]=0;
queue<int> Q;
Q.push(st);
while(!Q.empty())
{
st=Q.front();
Q.pop();
vis[st]=0;
for(i=first[st];i!=-1;i=nex[i])
{
int to=(zf?v[i]:u[i]);
if(dis[to]>dis[st]+w[i])
{
dis[to]=dis[st]+w[i];
if(!vis[to])
{
vis[to]=1;
Q.push(to);
}
}
}
}
}
void fz()
{
int i;
for(i=0;i<=p;i++)
first[i]=nex[i]=-1;
for(i=0;i<p;i++)
{
nex[i]=first[v[i]];
first[v[i]]=i;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>c>>p;
int i;
for(i=0;i<=p;i++)
first[i]=nex[i]=-1;
for(i=0;i<p;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
nex[i]=first[u[i]];
first[u[i]]=i;
}
spfa(1,1);
int ans=0;
for(int i=2;i<=c;i++)
ans+=dis[i];
fz();
spfa(1,0);
for(int i=2;i<=c;i++)
ans+=dis[i];
printf("%d\n",ans);
}
return 0;
}