线性基+图
求1到n的最大异或;
把环都记录下来,然后弄到线性基,答案的初始值是1到n的任意一条路径。
#include <cstdio>
#include <cstring>
typedef long long LL;
LL p[70], circle[1000010], d[1000010];
int cnt = 0, ct = 0, head[1000010], vis[1000010];
struct edge
{
int next, to;
LL w;
}G[1000010];
void add(int u, int v, LL w) {
G[cnt].w = w;
G[cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int x) {
vis[x] = 1;
for(int i = head[x]; i != -1; i = G[i].next) {
int v = G[i].to;
if(vis[v]) circle[ct++] = d[v]^d[x]^G[i].w;
else {
d[v] = d[x]^G[i].w;
dfs(v);
}
}
}
int main() {
memset(head, -1, sizeof(head));
int n, m;
scanf("%d %d", &n, &m);
while(m--) {
int u, v;
LL w;
scanf("%d %d %lld", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
dfs(1);
LL ans = d[n];
for(int i = 0; i < ct; i++) {
for(int j = 60; j >= 0; j--) {
if(circle[i] & (1LL << j)) {
if(p[j] == 0) {
p[j] = circle[i];
break;
}
circle[i] ^= p[j];
}
}
}
for(int i = 60; i >= 0; i--) {
if((ans ^ p[i]) > ans) ans ^= p[i];
}
printf("%lld
", ans);
return 0;
}