题意:
给定一个有向图,求往返的最小距离。
很简单,正向求一次最短路,再反向求一次最短路,结果相加就好了。
但是题目给定的数据比较大,有1000000个点,用点存边肯定要爆内存,所以要以边存点。
嗯,下面开始上代码了:
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1000005,inf=1000000005;
struct node{
int y,w,next;
}e[1000005];
int h[maxn],w[maxn],x[maxn],y[maxn],d[maxn];
int visit[maxn];
int n,m,p;
long long ans;
queue<int>q;
void init(int x,int y,int w){
e[++p].y=y;
e[p].w=w;
e[p].next=h[x];
h[x]=p;
}
void spfa(){
int i,x,y;
for(i=1;i<=n;i++){
d[i]=inf;
visit[i]=0;
}
q.push(1);
visit[1]=1;
d[1]=0;
while(!q.empty()){
x=q.front();
q.pop();
for(i=h[x];i;i=e[i].next){
y=e[i].y;
if(e[i].w+d[x]<d[y]){
d[y]=e[i].w+d[x];
if(!visit[y]){
visit[y]=1;
q.push(y);
}
}
}
}
}
int main(){
int t,i,j;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
p=0;
memset(h,0,sizeof(h));
for(i=0;i<m;i++){
scanf("%d%d%d",&x[i],&y[i],&w[i]);
init(x[i],y[i],w[i]);
}
spfa();
ans=0;
for(i=1;i<=n;i++)
ans+=d[i];
memset(h,0,sizeof(h));
p=0;
for(i=0;i<m;i++)
init(y[i],x[i],w[i]);
spfa();
for(i=1;i<=n;i++)
ans+=d[i];
printf("%I64d\n",ans);
}
return 0;
}