Description
给定一棵n个点的带权树,求树上最长的异或和路径
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
1 2 3
2 3 4
2 4 6
1 2 3
2 3 4
2 4 6
Sample Output
7
HINT
The xor-longest path is 1->2->3, which has length 7 (=3 ⊕ 4)
注意:结点下标从1开始到N....
题解:两个点到根的异或和异或一下就是这两个点之间的异或和。
所以只要统计出所有点到根的异或和,放到trie树里面。
然后在trie树里面依次查询每个点的最大异或即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100010
using namespace std;
int point[N],next[N<<1],x,y,v,cnt,n,ans,a[N];
struct use{int st,en,v;}e[N<<1];
struct trie{
int ch[N*30][2],cnt;
void insert(int x){
int now(0);
for (int i=30;i>=0;i--){
int t=x&(1<<i);t>>=i;
if (!ch[now][t]) ch[now][t]=++cnt;
now=ch[now][t];
}
}
int query(int x){
int now(0),temp(0);
for (int i=30;i>=0;i--){
int t=x&(1<<i);t>>=i;
if (ch[now][t^1]) temp+=1<<i,now=ch[now][t^1];
else now=ch[now][t];
}
return temp;
}
}trie;
void add(int x,int y,int v){
next[++cnt]=point[x];point[x]=cnt;e[cnt].en=y;e[cnt].v=v;
}
void dfs(int x,int fa){
for (int i=point[x];i;i=next[i])
if (e[i].en!=fa){
a[e[i].en]=a[x]^e[i].v;
dfs(e[i].en,x);
}
}
int main(){
scanf("%d",&n);
for (int i=1;i<n;i++){
scanf("%d%d%d",&x,&y,&v);
add(x,y,v);add(y,x,v);
}
dfs(1,0);
for (int i=1;i<=n;i++) trie.insert(a[i]);
for (int i=1;i<=n;i++)
ans=max(ans,trie.query(a[i]));
cout<<ans<<endl;
}