[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;
}
标签:now,ba,val,int,题解,Path,Problem,include
From: https://www.cnblogs.com/MoyouSayuki/p/18088015