问题转化为一些数里面选两个数异或和最大。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 200500 #define maxe 300500 using namespace std; int n,x,y,z,g[maxv],nume=1,dis[maxv],root,tot=0,ls[maxv<<5],rs[maxv<<5],bin[35],ans=0; struct edge { int v,w,nxt; }e[maxe]; void addedge(int u,int v,int w) { e[++nume].v=v;e[nume].w=w; e[nume].nxt=g[u];g[u]=nume; } void dfs(int x,int fath) { for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath) { dis[v]=dis[x]^e[i].w; dfs(v,x); } } } void insert(int &now,int x,int bit) { if (!now) now=++tot; if (bit==-1) return; int nb=x&bin[bit]; if (!nb) insert(ls[now],x,bit-1); else insert(rs[now],x,bit-1); } void build() { bin[0]=1; for (int i=1;i<=31;i++) bin[i]=bin[i-1]<<1; for (int i=1;i<=n;i++) insert(root,dis[i],31); } int ask(int now,int x,int bit) { if (bit==-1) return 0; int nb=x&bin[bit]; if (!nb) { if (rs[now]) return ask(rs[now],x,bit-1)+bin[bit]; else return ask(ls[now],x,bit-1); } else { if (ls[now]) return ask(ls[now],x,bit-1)+bin[bit]; else return ask(rs[now],x,bit-1); } } int main() { scanf("%d",&n); for (int i=1;i<=n-1;i++) { scanf("%d%d%d",&x,&y,&z); addedge(x,y,z);addedge(y,x,z); } dfs(1,0); build(); for (int i=1;i<=n;i++) ans=max(ans,ask(root,dis[i],31)); printf("%d\n",ans); return 0; }