专栏文章
题解:AT_abc395_e [ABC395E] Flip Edge
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miq33758
- 此快照首次捕获于
- 2025/12/03 22:10 3 个月前
- 此快照最后确认于
- 2025/12/03 22:10 3 个月前
题面
问题陈述
给定一个具有 个顶点和 条边的有向图。
第 条边 是从顶点 到顶点 的有向边。
最初,您位于顶点 。
您希望重复以下操作,直到到达顶点 :
-
执行以下两个操作之一:
-
沿一个方向移动,当前顶点的选定边。这会产生 的成本。更准确地说,如果在顶点 处,则选择顶点 ,使得存在从 到 的有向边。并移动到顶点 。
-
反转所有边的方向。这会产生 的成本。 更准确地说,当且仅当在该操作之前存在从 到 的有向边,在此操作之后,立即存在从 到 的有向边。对于给定的图,通过重复这些操作,可以保证从顶点 到达顶点 。
-
查找到达顶点 所需的最小总成本。
数据范围
-
-
-
-
-
-
对于给定的图,保证可以通过所描述的操作从顶点 到达顶点 。
-
所有输入值均为整数。
思路
如果没有反边的话,就是最普通的最短路,所以这题的注意点就是如何处理反边做法:
建立分层图,第一层是原图,第二层是反边图。
- 那么同层图直接的边权就是1;
- 如果要跨层的话就要付出 的代价;
- 题目就变成了最普通的最短路,答案为 。
Code
CPP#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;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...