《命運2》官方支援“拯救新光行動” 將獎勵幫助新手的老玩家
阿新 • • 發佈:2022-01-07
\(\text{Solution}\)
通過觀察發現答案路徑為一條鏈和一些簡單環組成
環可選可不選,可用過線性基決定(異或最大值)
鏈的選擇不影響答案(考慮多條鏈必然產生環,涉及的環的異或值是同樣的)
那麼我們就只要任取一條鏈並藉助返祖邊找到簡單環,線性基弄出答案即可
\(\text{Code}\)
#include <cstdio> #include <iostream> #define IN inline #define RE register #define LL long long using namespace std; const int N = 1e5 + 5; int n, m, tot, h[N], vis[N]; LL dis[N]; struct edge{int to, nxt; LL w;}e[N << 1]; IN void add(int x, int y, LL z){e[++tot] = edge{y, h[x], z}, h[x] = tot;} LL p[N]; IN void insert(LL x) { for(RE int i = 61; i >= 0; i--) if ((x >> i) & 1) if (!p[i]){p[i] = x; return;} else x ^= p[i]; } IN void dfs(int x, LL d) { vis[x] = 1, dis[x] = d; for(RE int i = h[x]; i; i = e[i].nxt) { int v = e[i].to; if (!vis[v]) dfs(v, d ^ e[i].w); else if (e[i].w ^ dis[x] ^ dis[v]) insert(e[i].w ^ dis[x] ^ dis[v]); } } int main() { scanf("%d%d", &n, &m); LL w; for(RE int i = 1, u, v; i <= m; i++) scanf("%d%d%lld", &u, &v, &w), add(u, v, w), add(v, u, w); dfs(1, 0); LL ans = dis[n]; for(RE int i = 61; i >= 0; i--) ans = max(ans, ans ^ p[i]); printf("%lld\n", ans); }