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);
}
原文地址:https://www.cnblogs.com/qq8260573/p/10373147.html