AtCoder Beginner Contest 277 E // 最短路

Crystal Switches

题目来源:AtCoder Beginner Contest 277 E - Crystal Switches

题目链接:E - Crystal Switches (atcoder.jp)


题意

给定一个 N 个点 M 条边的无向图。每条边 {ui vi ai},表示 uivi 之间有一条初始状态为 ai 的无向边,当 ai=1,这条边初始可以使用,当 ai=0,这条边初始不能使用。图上有 K 个点,结点处有开关,当位于这些结点处时,可以按下开关,使得图上所有边的状态翻转。

求:从点 1 到点 N 的最短路。

数据范围:1N,M2×1050KN.

思路:最短路

考虑如何建图:

当图上开关总共按了偶数次时,初始状态为 1 的边是可以使用的;当图上开关总共按了奇数次时,初始状态为 0 的边是可以使用的。

于是,我们将每个点 x 拆成两个点:x,开关按下了偶数次时的结点 xx+N,开关按下了奇数次时的结点 x

  • 对于边 {u v 1},建出边 u1v
  • 对于边 {u v 0},建出边 u+N1v+N
  • 对于有开关的结点si,则建出边 si0si+N

建图之后,跑一遍起点为 1 的最短路,则要求的最短路就是 min(dist[N],dist[N+N]).

时间复杂度:O((M+K)·log(M+K)).

代码

#include <bits/stdc++.h>
#define endl '\n'
#define PII pair<int,int>
using namespace std;

const int N = 400010;
const int INF = 0x3f3f3f3f;

int n, m, k, dist[N], st[N];
vector<PII> g[N]; 

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    heap.push({0, 1});

    while(heap.size()) {
        auto t = heap.top();
        heap.pop();

        int u = t.second;
        if(st[u]) continue;
        st[u] = true;

        for(auto item : g[u]) {
            int v = item.first, w = item.second;
            if(dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                heap.push({dist[v], v});
            }
        }
    }
    
    int res = min(dist[n], dist[n + n]);
    return res == INF ? -1 : res;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> n >> m >> k;
    for(int i = 1; i <= m; ++ i) {
        int x, y, a;
        cin >> x >> y >> a;
        if(a) g[x].push_back({y, 1}), g[y].push_back({x, 1});
        else g[x + n].push_back({y + n, 1}), g[y + n].push_back({x + n, 1});
    }
    for(int i = 1; i <= k; ++ i) {
        int x;
        cin >> x;
        g[x].push_back({x + n, 0}), g[x + n].push_back({x, 0});
    }

    cout << dijkstra() << endl;

    return 0;
}
posted @   Jakon  阅读(169)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示