题意:就是求所有的节点到节点 1,然后从节点1返回的最小距离的和。
简单SPFA,和poj 3268 无多少差异。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x3f // 一个大数 #define eps 1e-6 using namespace std; #define maxn 1000050 #define Maxn 10000000 int n,m; int first[maxn]; int next[maxn]; int u[Maxn]; int v[Maxn]; int w[Maxn]; int dis[maxn]; int go[maxn]; int vist[maxn]; int a[Maxn],b[Maxn],c[Maxn]; queue<int> Q; void init() { memset(vist,0,sizeof(vist)); while(!Q.empty()) Q.pop();//一次spfa后记得清空队列 memset(dis,INF,sizeof(dis)); dis[1]=0; for(int i=1;i<=n;i++) first[i]=-1; } void spfa() { Q.push(1); vist[1]=1;//入列记为 1 while(!Q.empty()) { int t=Q.front(); Q.pop(); vist[t]=0;//出列记为 0 for(int i=first[t];i!=-1;i=next[i]) { if(dis[t]+w[i]<dis[v[i]]) { dis[v[i]]=dis[t]+w[i]; if(!vist[v[i]]) { Q.push(v[i]); vist[v[i]]=1; } } } } for(int i=1;i<=n;i++) go[i]+=dis[i]; } int main() { int T; cin>>T; while(T--) { memset(go,0,sizeof(go)); scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a[i],&b[i],&c[i]); u[i]=a[i]; v[i]=b[i]; w[i]=c[i]; next[i]=first[u[i]]; first[u[i]]=i; } spfa(); init(); for(int i=1;i<=m;i++) { v[i]=a[i]; u[i]=b[i]; w[i]=c[i]; next[i]=first[u[i]]; first[u[i]]=i; } spfa(); long long mm=0; for(int i=2;i<=n;i++) mm+=go[i]; printf("%I64d\n",mm); } return 0; }
poj1511 Invitation Cards
时间: 2024-11-06 16:36:54