P2865 [USACO06NOV]Roadblocks (次短路)
题意:给一张无向图,求这张图的严格次短路之长。
分析:
跑两次$dijkstra/SPFA$,分别求出$1$~$i$和$i$~$n$的最短路长度。
然后枚举一条次短路中的边$(u,v)$,计算$d[1,u]+e[u,v]+d[v,n]$的值($d$为最短路长),判断它是否严格满足次短路的要求:①比最短路长 ②在所有比最短路长的路径中最短
代码:
#include<bits/stdc++.h> using namespace std; const int N=5005,R=1e5+5; int n,r,cnt,fro[N],d[2][N]; bool vis[N]; struct edge{int x,y,w,nxt;}e[R<<1]; priority_queue<pair<int,int> > q; void add(int x,int y,int z) { e[++cnt].x=x,e[cnt].y=y,e[cnt].w=z; e[cnt].nxt=fro[x]; fro[x]=cnt; } void dijkstra(int s,int k) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) d[k][i]=1e8; d[k][s]=0; q.push(make_pair(0,s)); while(!q.empty()) { int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=fro[u];i;i=e[i].nxt) { int v=e[i].y; if(d[k][v]>d[k][u]+e[i].w) { d[k][v]=d[k][u]+e[i].w; q.push(make_pair(-d[k][v],v)); } } } } int main() { scanf("%d%d",&n,&r); int A,B,D; for(int i=1;i<=r;i++) { scanf("%d%d%d",&A,&B,&D); add(A,B,D),add(B,A,D); } dijkstra(1,0); dijkstra(n,1); int ans=1e8; for(int i=1;i<=cnt;i++) { int dis=d[0][e[i].x]+e[i].w+d[1][e[i].y]; if(dis>d[0][n]) ans=min(ans,dis); } printf("%d",ans); }
如有错误请指正。