刚刚知道一条性质:a^b=(a^c)^(b^c)。于是两点之间的异或值为其分别到根节点的异或值的异或。
用dfs求出每个点到根节点的异或值,并把每个值放在trie树上。注意:要从高位向低位建。
要使异或值最大,异或值为111...1,e.g.10101^01010=11111 ^-^
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 100005
struct node
{
int to,next,val;
}edge[inf<<1];
int head[inf];
int cnt;
void add(int f,int t,int v)
{
edge[cnt].to=t;
edge[cnt].val=v;
edge[cnt].next=head[f];
head[f]=cnt++;
}
int n;
int dis[inf],vis[inf];
void dfs(int x,int w)//求每个点到根节点的异或
{
dis[x]=w;
vis[x]=1;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
dfs(to,w^edge[i].val);
}
}
struct trie
{
int next[3];
}t[inf<<8];
int L;
void insert(int x)//建树
{
int a,p=0;
for(int i=30;i>=0;i--)
{
a=x&(1<<i)?1:0;
if(!t[p].next[a])//判断这位上有没有出现过这个数
{
t[p].next[a]=++L;//新建
t[L].next[0]=t[L].next[1]=0;//初始化
}
p=t[p].next[a];//向下移一位
}
}
int find(int x)
{
int a,p=0,w=0;
for(int i=30;i>=0;i--)
{
a=x&(1<<i)?0:1;//我们要找与这一位相反的数
if(t[p].next[a])
{
w|=(1<<i);//找到了就加上
p=t[p].next[a];
}else
{
p=t[p].next[!a];
}
}
return w;
}
void init()
{
memset(head,-1,sizeof(head));
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
cnt=0;
L=0;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
dfs(0,0);
t[0].next[0]=t[0].next[1]=0;
int ans=0;
for(int i=0;i<n;i++)
{
insert(dis[i]);
int u=find(dis[i]);
ans=max(ans,u);
}
printf("%d\n",ans);
}
}