bzoj2115
线性基+dfs树
我们先搞出dfs树,其实最终路径就是最初的路径和一些环异或。
环最多只有m-n+1,因为一共有m条边,然后有n-1条边在dfs树上,所以还剩m-n+1条边,都可以构成环。
所以dfs搞出环,线性基找最大值就可以了。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, ll> PII; const int N = 200010; int n, m, cnt; vector<PII> G[N]; ll a[N], d[N]; int used[N]; void gauss() { int now = 1; for(int i = 62; i >= 0; --i) { bool flag = false; for(int j = now; j <= cnt; ++j) if(a[j] & (1ll << i)) { swap(a[j], a[now]); flag = true; break; } if(!flag) continue; for(int j = 1; j <= cnt; ++j) if((a[j] & (1ll << i)) && j != now) a[j] ^= a[now]; ++now; } --now; } void dfs(int u, int last) { used[u] = 1; for(int i = 0; i < G[u].size(); ++i) { PII x = G[u][i]; int v = x.first; ll w = x.second; if(v == last) continue; if(!used[v]) { d[v] = d[u] ^ w; dfs(v, u); } else a[++cnt] = d[v] ^ d[u] ^ w; } } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= m; ++i) { int u, v; ll w; scanf("%d%d%lld", &u, &v, &w); G[u].push_back(make_pair(v, w)); G[v].push_back(make_pair(u, w)); } dfs(1, 0); ll ans = d[n]; gauss(); for(int i = 1; i <= 62 && i <= cnt; ++i) if((ans ^ a[i]) > ans) ans ^= a[i]; printf("%lld\n", ans); return 0; }