题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=129723
题目大意:n个点,m条边,求出从0到n的最短距离,输出途中经过的边的权值和并乘以2(最短路不唯一且有重边)
题目思路:spfa求出最短路,在反向推回去
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include <set> #include <map> #include <climits> #define MOD 10000007 using namespace std; #define N 10005 #define maxn 250050 #define inf 0x3f3f3f3f int n,m,head[N],d[N],vis[N],ans; struct Node{ int to,v,next; }node[maxn<<1]; ///因为是双向边,所以要开2倍 int n_cnt; inline void add(int x,int y,int v) { node[n_cnt].v=v; node[n_cnt].to=y; node[n_cnt].next=head[x]; head[x]=n_cnt++; } void init() { memset(d,inf,sizeof(d)); ///保存最短距离 memset(head,-1,sizeof(head)); ///边的头结点 memset(vis,0,sizeof(vis)); n_cnt=ans=0; } void spfa() { queue<int>q; d[0]=0; q.push(0); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u]; i+1; i=node[i].next) { int pos=node[i].to; if(d[pos]>d[u]+node[i].v) { d[pos]=d[u]+node[i].v; if(!vis[pos]) { q.push(pos); vis[pos]=1; } } } } } void _solve() { queue<int>q; q.push(n-1); int i; memset(vis,0,sizeof(vis)); vis[n-1]=1; while(!q.empty()) { int u=q.front();q.pop(); for(i=head[u]; i+1; i=node[i].next) { int pos=node[i].to; if(d[pos]+node[i].v==d[u]) ///如果从pos->u的距离满足条件,则符合题意 { ///满足的是最短路条件 ans+=node[i].v; if(!vis[pos]) { vis[pos]=1; q.push(pos); } } } } printf("%d\n",ans<<1); } int main() { int i,j,x,y,v; while(scanf("%d%d",&n,&m)!=EOF) { init(); for(i=0; i<m; ++i) { scanf("%d%d%d",&x,&y,&v); add(x,y,v); add(y,x,v); } spfa(); _solve(); } return 0; }
时间: 2024-10-09 10:03:59