题目大意
给定一个无向图,n点m边,求从1到n的所有路径中异或和最大的那条
分析
线性基神题啊(可能是我弱)
先随便搞一条路径。
从固定点到另外一个固定点的两条不相交路径异或值显然可以构成一个环的路径异或值。路径1^路径2=环
我们把它换一下:路径1=环^路径2
所以最优路径=初始路径^环1^环2……
那么我们搜索出每个环的异或值,问题就转化为求一个数和一堆数的最大异或和。
可以用线性基来搞。
代码
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 55000;
const int M = 220000;
long long read() {
char ch = getchar(); long long x = 0;
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
return x;
}
long long bin[70], dis[N], w[M], d[1100000], a[70];
int to[M], pre[N], nxt[M], top, cnt, n, m; bool vis[N];
void add(int u, int v, long long ww) {to[++top] = v; nxt[top] = pre[u]; w[top] = ww; pre[u] = top;}
void adds(int u, int v, long long w) {add(u, v, w); add(v, u, w);}
void dfs(int u) {
vis[u] = 1;
for(int i = pre[u]; i; i = nxt[i])
if(!vis[to[i]]) {dis[to[i]] = dis[u] ^ w[i]; dfs(to[i]);}
else d[++cnt] = dis[to[i]] ^ w[i] ^ dis[u];
}
void Insert(long long x) {
for(int i = 63; ~i && x; --i)
if(bin[i] & x)
a[i] = !a[i] ? x : a[i], x ^= a[i];
}
long long Query_max(long long ans) {for(int i = 63; ~i; --i) ans = !(ans & bin[i]) ? ans ^ a[i] : ans; return ans;}
int main() {
bin[0] = 1; for(int i = 1;i <= 63; ++i) bin[i] = bin[i - 1] << 1;
n = read(); m = read();
while(m--) {int u = read(), v = read(); long long w = read(); adds(u, v, w);}
dfs(1);
for(int i = 1;i <= cnt; ++i) Insert(d[i]);
printf("%lld\n", Query_max(dis[n]));
return 0;
}