传送门
直接把每个点到根节点的异或距离插入01trie。
然后枚举每个点在01trie上匹配来更新答案就行了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=1e5+5;
int son[N*32][2],rt=1,n,W,first[N],dis[N],cnt=0,tot=1,ans=0;
struct edge{int v,next,w;}e[N<<1];
inline void addedge(int u,int v,int w){e[++cnt].v=v,e[cnt].next=first[u],e[cnt].w=w,first[u]=cnt;}
inline void add(int u,int v,int w){addedge(u,v,w),addedge(v,u,w);}
void dfs(int p,int fa,int sum){
dis[p]=sum;
for(int i=first[p];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
dfs(v,p,sum^e[i].w);
}
}
inline void insert(int val){
int p=rt;
for(int i=31;~i;--i){
int tmp=(val>>i)&1;
if(!son[p][tmp])son[p][tmp]=++tot;
p=son[p][tmp];
}
}
inline int query(int val){
int ret=0,p=rt;
for(int i=31;~i;--i){
int tmp=(val>>i)&1;
ret<<=1;
if(son[p][tmp^1])++ret,p=son[p][tmp^1];
else p=son[p][tmp];
}
return ret;
}
int main(){
n=read();
for(int i=1,u,v,w;i<n;++i)u=read(),v=read(),w=read(),add(u,v,w);
dfs(1,0,0);
for(int i=1;i<=n;++i)insert(dis[i]);
for(int i=1;i<=n;++i)ans=max(ans,query(dis[i]));
printf("%d",ans);
return 0;
}