1. 程式人生 > 遊戲 >《命運2》官方支援“拯救新光行動” 將獎勵幫助新手的老玩家

《命運2》官方支援“拯救新光行動” 將獎勵幫助新手的老玩家

\(\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);
}