POJ3764 The xor-longest Path(字典树)

题意

给你一棵树,n个节点,n-1条边每条边i都有一个权值wi。定义任意两点间的权值为:这两点间的路径上的所有边的值的异或。比如a点和b点间有i,j,k三条边,那么ab两点间的权值为:wi^wj^wk。求这个最大的权值(最长异或路径)。

(n<=105)

题解

首先  边权可以放到点权上

然后我们可以搞一个树上的前缀异或和.
这样的话 把当前点的所有点权加到trie树里
从最高位到最低位走不同的路
例:1011100101
我们要走:0100011010
如果走不了就顺着走
跑出来的数异或当前的数就是经过这个点的最优解了

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const long long N=201000;
 8 long long ans,tot,cnt,head[N],n,mx,flag;
 9 struct edge{
10     long long to,nxt,w;
11 }e[N*2];
12 struct tree{
13     long long nxt[4];
14 }tr[N*50];
15 void insert(long long a){
16     long long now=0,z;
17     for(long long i=31;i>=1;i--){
18         if(a&(1<<(i-1)))z=1;
19         else z=0;
20         if(!tr[now].nxt[z]){
21             tr[now].nxt[z]=++tot;
22             memset(tr[tot].nxt,0,sizeof(tr[tot].nxt));
23         }
24         now=tr[now].nxt[z];
25     }
26 }
27 void check(long long x){
28     long long tmp=0;
29     long long now=0,z;
30     for(long long i=31;i>=1;i--){
31         if(x&(1<<(i-1)))z=1;
32         else z=0;
33         if(tr[now].nxt[!z]){
34             tmp=(tmp<<1)+1;
35             now=tr[now].nxt[!z];
36         }
37         else{
38             tmp=tmp<<1;
39             now=tr[now].nxt[z];
40         }
41     }
42     ans=max(ans,tmp);
43 }
44 void add(long long u,long long v,long long w){
45     cnt++;
46     e[cnt].nxt=head[u];
47     e[cnt].to=v;
48     e[cnt].w=w;
49     head[u]=cnt;
50 }
51 void dfs1(long long u,long long f,long long w){
52     insert(w);
53     for(long long i=head[u];i;i=e[i].nxt){
54         long long v=e[i].to;
55         if(v==f)continue;
56         w^=e[i].w;
57         dfs1(v,u,w);
58         w^=e[i].w;
59     }
60 }
61 void dfs2(long long u,long long f,long long w){
62     check(w);
63     for(long long i=head[u];i;i=e[i].nxt){
64         long long v=e[i].to;
65         if(v==f)continue;
66         w^=e[i].w;
67         dfs2(v,u,w);
68         w^=e[i].w;
69     }
70 }
71 int main(){
72     while(~scanf("%lld",&n)){
73         ans=0;cnt=0;tot=0;mx=0;flag=0;
74         memset(head,0,sizeof(head));
75         memset(tr[0].nxt,0,sizeof(tr[0].nxt));
76         for(long long i=1;i<=n-1;i++){
77             long long u,v,w;
78             scanf("%lld%lld%lld",&u,&v,&w);
79             u++;v++;
80             add(u,v,w);
81             add(v,u,w);
82         }
83         insert(0);
84         dfs1(1,0,0);
85         dfs2(1,0,0);
86         printf("%lld\n",ans);
87     }
88     return 0;
89 }

猜你喜欢

转载自www.cnblogs.com/Xu-daxia/p/9559154.html