给定一棵 nn 个点的带权树,结点下标从 11 开始到 nn。寻找树中找两个结点,求最长的异或路径。
异或路径指的是指两个结点之间唯一路径上的所有边权的异或。
处理出每个点的树上异或前缀
这些异或值按照二进制数插入Trie
经典问题了
#include <iostream>
#include <cstring>
using namespace std;
const int N=1e6+10,M=N;
int tot=1,ch[N][2];
int n,nxt[M],go[M],hd[N],w[M],all=1;
int g[N];
void add_(int x,int y,int z){
go[++all]=y; w[all]=z;nxt[all]=hd[x]; hd[x]=all;
}
void dfs(int x,int fa){
for(int i=hd[x];i;i=nxt[i]){
int y=go[i],z=w[i]; if(y==fa) continue;
g[y]=z^g[x];
dfs(y,x);
}
}
void insert(int num){
int u=1,c;
for(int i=31;i>=0;i--){
c=(num>>i)&1;
if(ch[u][c]==0) ch[u][c]=++tot;
u=ch[u][c];
}
}
int find(int num){
int u=1,c,t=0;
for(int i=31;i>=0;i--){
c=(num>>i)&1;
if(ch[u][c^1]) u=ch[u][c^1],t=t*2+1;
else u=ch[u][c],t*=2;
}
return t;
}
signed main(){
cin>>n;
int x,y,z,ans=0;
for(int i=1;i<n;i++)
cin>>x>>y>>z,add_(x,y,z),add_(y,x,z);
dfs(1,0);
for(int i=1;i<=n;i++){
ans=max(ans,find(g[i]));
insert(g[i]);
}
cout<<ans;
}
浙公网安备 33010602011771号