题解:AT_abc395_e [ABC395E] Flip Edge

· · 个人记录

题面

问题陈述

给定一个具有 N 个顶点和 M 条边的有向图。

i 条边 (1 \leq i \leq M) 是从顶点 u _ i 到顶点 v _ i 的有向边。

最初,您位于顶点 1

您希望重复以下操作,直到到达顶点 N

查找到达顶点 N 所需的最小总成本。

数据范围

思路

如果没有反边的话,就是最普通的最短路,所以这题的注意点就是如何处理反边做法:

建立分层图,第一层是原图,第二层是反边图。

Code

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pll pair<ll,ll>
const ll INF=1e18;
const int N=1e6+5;
vector<array<int,2>>g[N];
vector<ll> dijk(int n,int s=1){
    priority_queue<pll,vector<pll>,greater<pll>>q; 
    vector<int>vis(2*n+10, 0);
    vector<ll>dis(2*n+10, 1e18);
    q.push({0,s});
    dis[s]=0;
    while(!q.empty()){
        int u=q.top().second; 
        q.pop();
        if(vis[u]){
            continue;   
        }
        vis[u]=1;
        for(auto [v,w]:g[u]){
            if(dis[u]+w<dis[v]){
                dis[v]=dis[u]+w;
                q.push({dis[v],v});
            }
        }
    }
    return dis;
}
int main(){
    int n,m,x;
    cin>>n>>m>>x;
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        g[u].push_back({v,1});
        g[v+n].push_back({u+n,1});
    }
    for(int i=1;i<=n;i++){
        g[i].push_back({i+n,x});
        g[i+n].push_back({i,x});
    }
    auto dis=dijk(n,1);
    cout<<min(dis[n],dis[2*n])<<endl;
    return 0;
}