题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66569#problem/J
题意:给定一个起点,求其他点到起点和起点到其他点的最短距离的和的总和值。和POJ 3268 Silver Cow Party差不多。
思路:用SPFA求出单源点最短距离即可,最后求出总和值就好了。不只是我理解错了还是咋的,题目中的sum,我还以为是总和值,所以稳稳的把sum设成了int,WA。设为LL就过了。。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define INF 0x7fffffff
#define LL __int64
using namespace std;
struct edge{
int u,v,w;
}E[1000010];
int P,Q,vis[1000010];
vector<int> F[2][1000010];
LL dis[2][1000010];
void bfs(int op){//op为0更新边的前驱,op为1是更新边的后驱
memset(vis,0,sizeof(vis));
for(int i=0;i<=P;i++) dis[op][i]=INF;
queue<int> Q;
Q.push(1);vis[1]=1;dis[op][1]=0;
while(!Q.empty()){
int tp=Q.front();Q.pop();vis[tp]=0;
for(int i=0;i<(int)F[op][tp].size();i++){
int k=F[op][tp][i];
int u=E[k].u,v=E[k].v,w=E[k].w;
if(!op) swap(u,v);
if(dis[op][u]+w>=dis[op][v]) continue;
dis[op][v]=dis[op][u]+w;
if(!vis[v]) vis[v]=1,Q.push(v);
}
}
}
int main(){
//freopen("D:in.txt","r",stdin);
int T;cin>>T;
while(T--){
cin>>P>>Q;
for(int i=0;i<=P;i++) F[0][i].clear(),F[1][i].clear();
int a,b,c;
for(int i=0;i<Q;i++){
scanf("%d %d %d",&a,&b,&c);
E[i]=(edge){a,b,c};
F[0][b].push_back(i);F[1][a].push_back(i);
}
bfs(0);bfs(1);
LL sum=0;
for(int i=1;i<=P;i++) sum=sum+dis[0][i]+dis[1][i];
printf("%I64d\n",sum);
}
return 0;
}