POJ 3764 The xor-longest Path trie树解决位运算贪心

题意 :  一颗树,每个边有个值,在树上找一条简单路径,使得这条路径上的边权异或值最大
先找到所有节点到一点的距离 , 显然dis( x , y ) = dis( z , x )^dis( z , y )
那么把所有的距离都以二进制由高到低存到trie中 , 扫一遍每个点 , 在trie树上由高到低找某位与该点某位相反的数 , 找不到则妥协找下一位 , 如此贪心即可 
写的时候超空间一次re两次,trie树的大小设置为30*n刚好,不要想太多设置太大或者因为走极端设置得过小...就按数据量设置就可以...
代码
 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\n",ans);
97     }
98     return 0;
99 }
View Code

 

posted @ 2017-11-05 08:35  鲸头鹳  阅读(146)  评论(0编辑  收藏  举报