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:
⊕ 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
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)
这题有LCA内味了。注意到异或的性质,设d[x]为根节点到x的路径的异或值,则x到y的异或值实际上就是d[x] xor d[y],因为根节点到LCA(x,y)的这段路径自己异或了两次相当于什么都没有变。因此问题转化为从d数组挑选两个数使得其异或值最大,就变成01字典树了。
坑点:多组输入,记得及时清空数组以及ans,tot等变量,数组开两倍建反向边。略微卡点时间,因此尽量采取快一点的写法和输入输出等。
#include <iostream> #include <cstdio> #include <string> #include <cmath> #include <algorithm> #include <cstring> #define N 100005 using namespace std; int n,head[N],ver[2*N],Next[2*N],edge[2*N],ttot=0,d[N]; int trie[100005*31][2],tot=1,ans=0; void add(int x,int y,int z) { ver[++ttot]=y,edge[ttot]=z,Next[ttot]=head[x],head[x]=ttot; } void dfs(int x,int pre,int sum) { int i; for(i=head[x];i;i=Next[i]) { int y=ver[i],z=edge[i]; if(y==pre) continue; d[y]=z^sum; dfs(y,x,d[y]); } } int fpow(int a,int b) { int ans=1; for(;b;b>>=1) { if(b&1) ans=ans*a; a=a*a; } return ans; } void insert(int x) { int p=1,k; for(k=30;k>=0;k--) { int temp=x&(1<<k)?1:0; if(trie[p][temp]==0) trie[p][temp]=++tot; p=trie[p][temp]; } } int search(int x)//返回最大的异或值 { int k,p=1,num=0; for(k=30;k>=0;k--) { int orip=p,temp=x&(1<<k)?1:0; p=trie[p][1-temp];//防止p被更改 if(p==0) { p=trie[orip][temp];//退而求其次 } else { num+=fpow(2,k); } } return num; } int main() { while(scanf("%d",&n)!=EOF) { memset(head,0,sizeof(head)); memset(Next,0,sizeof(Next)); memset(edge,0,sizeof(edge)); memset(ver,0,sizeof(ver)); memset(trie,0,sizeof(trie)); tot=1,ttot=0,ans=0; int i; for(i=1;i<=n-1;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(0,-1,0); for(i=0;i<n;i++) { insert(d[i]); } for(i=0;i<n;i++) { ans=max(ans,search(d[i])); } cout<<ans<<endl; } return 0; }