In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:
{xor}length§=\oplus{e \in p}w(e)
⊕ is the xor operator.
We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?
Input
The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.
Output
For each test case output the xor-length of the xor-longest path.
Sample Input
4
0 1 3
1 2 4
1 3 6
Sample Output
7
Hint
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
先dfs 出根节点到各个节点的 xor 和,然后就是在这样的一个序列中选出两个xor最大;
那么字典树即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 6000005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const long long int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-6
#define pll pair<ll,ll>
ll quickpow(ll a, ll b) {
ll ans = 1;
a = a % mod;
while (b > 0) {
if (b % 2)ans = ans * a;
b = b / 2;
a = a * a;
}
return ans;
}
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a%b);
}
int d[maxn][2], cnt;
struct edge {
int to, w, nxt;
edge(){}
edge(int x,int y,int z):to(x),w(y),nxt(z){}
}e[500005];
int num[200005], vis[200005], tot, head[200005];
void addedge(int from, int to, int w) {
e[tot] = edge(to, w, head[from]);
head[from] = tot++;
}
void dfs(int v, int w) {
vis[v] = 1;
num[v] = w;
for (int i = head[v]; i != -1; i = e[i].nxt) {
if (!vis[e[i].to]) {
dfs(e[i].to, w^e[i].w);
}
}
}
void add(int x) {
int p = 1;
for (int i = 30; i >= 0; i--) {
if (d[p][(x >> i) & 1] == 0)
d[p][(x >> i) & 1] = ++cnt;
p = d[p][(x >> i) & 1];
}
}
int fid(int x) {
int p = 1, ans = 0;
for (int i = 30; i >= 0; i--) {
int t = (x >> i) & 1;
if (d[p][t ^ 1]) {
ans += (1 << i);
p = d[p][t ^ 1];
}
else p = d[p][t];
}
return ans;
}
int main()
{
//ios::sync_with_stdio(false);
int n;
while (scanf("%d",&n)!=EOF) {
tot = 0;
ms(d); ms(vis);
memset(head, -1, sizeof(head));
cnt = 1;
for (int i = 1; i < n; i++) {
int x, y, w;
//cin >> x >> y >> w;
scanf("%d%d%d", &x, &y, &w);
addedge(x, y, w); addedge(y, x, w);
}
dfs(0, 0);
int ans = 0;
for (int i = 0; i < n; i++) {
add(num[i]);
ans = max(ans, fid(num[i]));
}
cout << ans << endl;
}
}