0x10:最长异或值路径
先dfs求出每个点到root的异或值,记为a[i]。
则有u到v的异或值等于a[u] xor a[v].
证明:如果u,v在root的不同子树中,则显然。否则,u到root的路径与v到root的路径会有重叠的部分,而这部分恰被计算两次,由xor的性质(x xor x = 0),不会产生影响。
于是问题规约为,找一对(u,v),使a[u] xor a[v]最大。
用上一题的板子就好了。
//Wan Hong 2.2
//home
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
typedef std::string str;
#define INF (1ll<<58)
ll read()
{
char c;
ll f=1,x=0;
do
{
c=getchar();
if(c=='-')f=-1;
}while(c<'0'||c>'9');
do
{
x=x*10+c-'0';
c=getchar();
}while(c>='0'&&c<='9');
return f*x;
}
ll max(ll a,ll b)
{
return a>b?a:b;
}
ll min(ll a,ll b)
{
return a<b?a:b;
}
bool umax(ll& a,ll b)
{
if(b>a)return a=b,1;
return 0;
}
bool umin(ll& a,ll b)
{
if(b<a)return a=b,1;
return 0;
}
/**********/
#define MAXN 100011
struct Trie
{
ll t[2][MAXN*32+1],cnt;
ll a[35];
Trie()
{
cnt=1;
}
void insert(ll x)
{
for(ll i=1;i<=32;++i)
a[i]=(x&1),x>>=1;
ll u=1;
for(ll i=32;i;--i)
{
//putchar(a[i]+'0');
ll &v=t[a[i]][u];
if(!v)v=++cnt;
u=v;
}
}
ll query(ll x)
{
for(ll i=1;i<=32;++i)
a[i]=(x&1),x>>=1;
ll u=1,res=0;
for(ll i=32;i;--i)
{
//putchar(a[i]+'0');
if(t[!a[i]][u])
{
res+=1<<(i-1);
u=t[!a[i]][u];
}
else if(t[a[i]][u])
{
u=t[a[i]][u];
}
else return res;
}
return res;
}
}t;
struct Edge
{
ll v,w,nxt;
}e[MAXN<<1|1];
ll cnt=0,last[MAXN];
void adde(ll u,ll v,ll w,bool p=1)
{
++cnt;
e[cnt].v=v;e[cnt].w=w;
e[cnt].nxt=last[u];last[u]=cnt;
if(p)adde(v,u,w,0);
}
ll a[MAXN];
void dfs(ll u,ll fa=0)
{
for(ll i=last[u];i;i=e[i].nxt)
{
ll v=e[i].v;
if(v==fa)continue;
a[v]=a[u]^e[i].w;
dfs(v,u);
}
}
int main()
{
ll n=read(),ans=0;
for(ll i=1;i<n;++i)
{
ll u=read(),v=read(),w=read();
adde(u,v,w);
}
dfs(1);
for(ll i=1;i<=n;++i)
{
umax(ans,t.query(a[i]));
t.insert(a[i]);
}
printf("%lld",ans);
return 0;
}