The simple greedy Trie idea, as long as the XOR path is found to be the XOR value of the two paths to the root node, then the Trie tree is greedy
#include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queue> #include<set> #define ull unsigned long long using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pair<int,int> > plll; const int N=3e5+10; const int inf=0x3f3f3f3f; int tr[3000001][2]; int h[N],ne[N],e[N],w[N],idx; int cnt; int sum[N]; void add(int a,int b,int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } void dfs(int u,int res,int fa){ int i; sum[u]=res; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; int c=w[i]; dfs(j,res^c,u); } } void insert(int x){ int i; int cur=0; for(i=30;i>=0;i--){ int num=x>>i&1; if(tr[cur][num]==0) tr[cur][num]=++cnt; cur=tr[cur][num]; } } int search(int x){ int cur=0; int i; int res=0; for(i=30;i>=0;i--){ int num=x>>i&1; if(tr[cur][num^1]){ res+=1<<i; cur=tr[cur][num^1]; } else{ cur=tr[cur][num]; } } return res; } int main(){ memset(h,-1,sizeof h); int n; cin>>n; int i; for(i=1;i<n;i++){ int u,v,c; scanf("%d%d%d",&u,&v,&c); add(u,v,c); add(v,u,c); } dfs(1,0,-1); for(i=0;i<n;i++){ insert(sum[i]); } int res=0; for(i=0;i<n;i++){ res=max(res,search(sum[i])); } cout<<res<<endl; }