[CF845G] Shortest Path Problem? 题解

[CF845G] Shortest Path Problem? 题解

注意到如果我们在路径中多走了一个环,那么得到的贡献就是这个环的贡献。

对于这种有关环的问题,考虑一棵生成树,这样所有环都可以用一条祖先边和一些树边组成,发现选环走的过程是独立的,考虑把所有环的权值丢进线性基里,然后查询 xordist[1] ^ xordist[n] 异或线性基子集的最小值。

时间复杂度:\(O((n + m)\log V)\)

// Contest: Luogu
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2023-12-07 00:39:45

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, B = 32;

int n, m, val[N];
vector<PII> g[N];
int ba[B];
void insert(int x) {
    for(int i = B - 1; ~i; i --)
        if(x >> i & 1) {
            if(!ba[i]) return void(ba[i] = x);
            x ^= ba[i];
        }
}
void dfs(int u, int now) {
    val[u] = now;
    for(auto [v, w] : g[u]) {
        if(val[v] == -1) dfs(v, now ^ w);
        else insert(now ^ w ^ val[v]);
    }
}
int Qmin(int x) {
    for(int i = B - 1; ~i; i --) 
        if(ba[i] && (x >> i & 1))
            x ^= ba[i];
    return x;
}
signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for(int i = 1, a, b, c; i <= m; i ++) {
        cin >> a >> b >> c;
        g[a].push_back({b, c}), g[b].push_back({a, c});
    }
    memset(val, -1, sizeof val);
    dfs(1, 0);
    cout << Qmin(val[n]) << '\n';

    return 0;
}
posted @ 2024-03-21 18:36  MoyouSayuki  阅读(4)  评论(0编辑  收藏  举报
:name :name