题意 : 一颗树,每个边有个值,在树上找一条简单路径,使得这条路径上的边权异或值最大
先找到所有节点到一点的距离 , 显然dis( x , y ) = dis( z , x )^dis( z , y )
那么把所有的距离都以二进制由高到低存到trie中 , 扫一遍每个点 , 在trie树上由高到低找某位与该点某位相反的数 , 找不到则妥协找下一位 , 如此贪心即可
写的时候超空间一次re两次,trie树的大小设置为30*n刚好,不要想太多设置太大或者因为走极端设置得过小...就按数据量设置就可以...
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=100010; 9 const double eps=1e-8; 10 const long long modn=1000; 11 int n; 12 int ans=0; 13 struct nod{ 14 int y; 15 int next; 16 int v; 17 }e[maxn*2]; 18 int head[maxn]={},tot=0; 19 int dis[maxn]={}; 20 struct tri{ 21 bool exist; 22 int v; 23 int next[2]; 24 }a[maxn*30]; 25 int tot1=0; 26 void init(int x,int y,int z){ 27 e[++tot].y=y; 28 e[tot].v=z; 29 e[tot].next=head[x]; 30 head[x]=tot; 31 } 32 void doit(int x,int v,int k){ 33 if(k<0){ 34 a[x].exist=1; 35 a[x].v=v; 36 return; 37 }int z; 38 if(v&(1<<k)){ 39 z=1; 40 }else{ 41 z=0; 42 } 43 if(!a[x].next[z]){ 44 a[x].next[z]=++tot1; 45 }doit(a[x].next[z],v,k-1); 46 } 47 void getit(int x,int v,int k){ 48 if(k<0){ 49 int z=v^a[x].v; 50 ans=max(ans,z); 51 return; 52 }int z; 53 if(v&(1<<k)){ 54 z=0; 55 }else{ 56 z=1; 57 } 58 if(!a[x].next[z]){ 59 z=1^z; 60 }getit(a[x].next[z],v,k-1); 61 } 62 void dfs(int x,int fa,int val){ 63 int y,v,z; 64 for(int i=head[x];i;i=e[i].next){ 65 y=e[i].y; 66 v=e[i].v; 67 if(y!=fa){ 68 z=val^v; 69 dis[y]=z; 70 dfs(y,x,z); 71 } 72 } 73 } 74 void yu(){ 75 memset(a,0,sizeof(a)); 76 memset(e,0,sizeof(e)); 77 memset(head,0,sizeof(head)); 78 tot1=tot=0; 79 memset(dis,0,sizeof(dis)); 80 ans=0; 81 } 82 int main(){ 83 while(~scanf("%d",&n)){ 84 yu(); 85 int x,y,z; 86 for(int i=1;i<n;i++){ 87 scanf("%d%d%d",&x,&y,&z); 88 init(x+1,y+1,z); 89 init(y+1,x+1,z); 90 } 91 dfs(1,0,0); 92 for(int i=1;i<=n;i++){ 93 getit(0,dis[i],30); 94 doit(0,dis[i],30); 95 } 96 printf("%d ",ans); 97 } 98 return 0; 99 }