标签:
题目连接:
http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129723
题意:
给你一个n点m图的边
1到n有多条最短路,问你所有经过的边的总和*2是多少
题解:
对1,n分别求单源最短路径上spfa
枚举某条边是否为最短上的边
即 边权+disA[i] + disB[i] = 最短路长度,就是答案
#include<bits/stdc++.h> using namespace std; const int N = 1e6+20, M = 1e6+10, mod = 1e9+7, inf = 1e9+1000; typedef long long ll; int head[N],t,vis[N],dis[N],n,m,disA[N],disB[N]; struct edge{int to,value,next;}e[N*2]; void add(int u,int v,int w) {e[t].next=head[u],e[t].to=v,e[t].value=w;head[u]=t++;} void init(){ t = 0; memset(head,-1,sizeof(head)); } void spfa(int u) { for(int i=1;i<=n;i++) dis[i] = inf, vis[i] = 0; vis[1] = 1; dis[u] = 0; queue<int> q; q.push(u); while(!q.empty()) { int k = q.front();q.pop(); vis[k] = 0; for(int i=head[k];i!=-1;i=e[i].next) { int to = e[i].to; if(dis[k] + e[i].value < dis[to]) { dis[to] = dis[k] + e[i].value; if(!vis[to]) { q.push(to); vis[to] = 1; } } } } } int main() { while(~scanf("%d%d",&n,&m)) { init(); for(int i=1;i<=m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); a++,b++; add(a,b,c); add(b,a,c); } spfa(1); for(int i=1;i<=n;i++) disA[i] = dis[i]; spfa(n); for(int i=1;i<=n;i++) disB[i] = dis[i]; int mx = dis[1]; ll ans = 0; for(int i=1;i<=n;i++) { for(int j=head[i];j!=-1;j=e[j].next) { int to = e[j].to; int value = e[j].value; if(disA[i] + disB[to] + value == mx) ans+=value; } } printf("%lld\n",2ll*ans); } }
UVALive 6885 Flowery Trails 最短路枚举
标签:
原文地址:http://www.cnblogs.com/zxhl/p/5674847.html