bzoj1726: [Usaco2006 Nov]Roadblocks第二短路
作者:互联网
【题目大意】
求无向图点1到n的次短路。
【思路】
堆优化Dijkstra,方法就是一边跑Dijsktra一边就把次短路径保存下来。和一般Dijkstra不同的是把vis数组去掉了,因为还要生成次短路径。
重新写用的是SPFA。正反跑两次SPFA,然后枚举每一条边,如果起点到一个端点的最短路+另一个端点到终点的最短路+长度 ≠ 最短路,则和答案比较,保存最小值。还是很好理解的
#include<bits/stdc++.h> using namespace std; const int MAXR=1e5+5; const int MAXN=5e3+5; const int INF=21e8; struct edge { int to,len; }; vector<edge> E[MAXN]; int n,r,dis[MAXN],inque[MAXN],dis1[MAXN],dis2[MAXN]; int u[MAXR],v[MAXR],w[MAXR]; void addedge(int u,int v,int w) { E[u].push_back((edge){v,w}); E[v].push_back((edge){u,w}); } void spfa(int S,int T) { for (int i=1;i<=n;i++) inque[i]=0,dis[i]=INF; queue<int> que; que.push(S); inque[S]=1;dis[S]=0; while (!que.empty()) { int head=que.front();que.pop(); inque[head]=0; for (int i=0;i<E[head].size();i++) { int nowdis=dis[head]+E[head][i].len,to=E[head][i].to; if (nowdis<dis[to]) { dis[to]=nowdis; if (!inque[to]) { que.push(to); inque[to]=1; } } } } } int main() { scanf("%d%d",&n,&r); for (int i=1;i<=r;i++) { scanf("%d%d%d",&u[i],&v[i],&w[i]); addedge(u[i],v[i],w[i]); } spfa(1,n); for (int i=1;i<=n;i++) dis1[i]=dis[i]; spfa(n,1); for (int i=1;i<=n;i++) dis2 [i]=dis[i]; int mx=dis1[n],ans=INF; for (int i=1;i<=r;i++) { int now=dis1[u[i]]+dis2[v[i]]+w[i]; if (now!=mx) ans=min(ans,now); now=dis1[v[i]]+dis2[u[i]]+w[i]; if (now!=mx) ans=min(ans,now); } printf("%d",ans); return 0; }
标签:int,短路,MAXR,Roadblocks,edge,que,MAXN,Nov,bzoj1726 来源: https://www.cnblogs.com/zzrblogs/p/10458390.html