日常刷题2025-3-3

日常刷题2025-3-3

E - Flip Edge

绿色

https://atcoder.jp/contests/abc395/tasks/abc395_e

思路:分层图最短路

建立一个正图和一个反图,反图的节点为正图的节点+n,从正图到反图和从反图到正图有边权为x的边。

整体跑一遍 dij 算法即可。

由于本题的边权只有两种情况,所以跑 01bfs 也可以过

代码

#include <bits/stdc++.h>
typedef std::pair<long long, long long> pll;
typedef std::pair<long long, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;
void solve(){
int n, m, x;
std::cin >> n >> m >> x;
std::vector g((n+1)*2, std::vector<pii>());
auto addedg = [&](int u, int v, int w)->void{
g[u].push_back({v, w});
};
for (int i = 0; i < m; i++){
int u, v; std::cin >> u >> v;
addedg(u, v, 1);
addedg(v+n, u+n, 1);
}
for (int i = 1; i <= n; i++){
addedg(i, i+n, x);
addedg(i+n, i, x);
}
std::vector<i64> dis((n+1)*2);
std::vector<bool> vis((n+1)*2);
std::priority_queue<pii, std::vector<pii>, std::greater<pii> > q;
for (int i = 1; i <= 2*n; i++) dis[i] = 1e18;
dis[1] = 0;
q.push({0, 1});
while (!q.empty()){
auto [_, v] = q.top();
q.pop();
if (vis[v]) continue;
vis[v] = true;
for (auto [to, w] : g[v]){
if (dis[to] > dis[v] + w){
dis[to] = dis[v] + w;
q.push({dis[to], to});
}
}
}
std::cout << (std::min(dis[n], dis[2*n])) << '\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18747996

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   califeee  阅读(6)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.