简单的贪心Trie思路,只要发现异或和路径就是两个到根节点的路径的异或值就行,之后Trie树贪心
#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; }