Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 6361 | Accepted: 1378 |
Description
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)
Source
trie树+贪心
DFS预处理出每个结点到根的路径的异或和。两点之间路径的异或和等于各自到根的路径的异或和的异或。
将所有的异或和转化成二进制串,建成trie树。
对于每个二进制串,在trie树上贪心选取使异或值最大的路径(尽量通往数值相反的结点),记录最优答案。
↑为了防止匹配到自身的一部分,每个二进制串都应该先查完再插入trie树。
/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct edge{
int v,nxt,w;
}e[mxn<<];
int hd[mxn],mct=;
void add_edge(int u,int v,int w){
e[++mct].v=v;e[mct].nxt=hd[u];e[mct].w=w;hd[u]=mct;return;
}
int t[mxn*][],cnt=;
int n,ans=;
int f[mxn];
void insert(int x){
int now=;
for(int i=;i>=;i--){
int v=(x>>i)&;
if(!t[now][v])t[now][v]=++cnt;
now=t[now][v];
}
return;
}
void query(int x){
int now=;
int res=;
for(int i=;i>=;i--){
int v=(x>>i)&;
if(t[now][v^]){
v^=;
res+=(<<i);
}
now=t[now][v];
}
ans=max(res,ans);
return;
}
void DFS(int u,int fa,int num){
f[u]=num;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa)continue;
DFS(v,u,num^e[i].w);
}
return;
}
void init(){
memset(hd,,sizeof hd);
memset(t,,sizeof t);
// memset(f,0,sizeof f);
mct=;cnt=;ans=;
return;
}
int main(){
while(scanf("%d",&n)!=EOF){
init();
int i,j,u,v,w;
for(i=;i<n;i++){
u=read();v=read();w=read();
u++;v++;
add_edge(u,v,w);
add_edge(v,u,w);
}
DFS(,,);
for(i=;i<=n;i++){
// printf("f[%d]:%d\n",i,f[i]);
query(f[i]);
insert(f[i]);
}
printf("%d\n",ans);
}
return ;
}