【bzoj1954】【The xor-longest Path】【trie树】

Description

《【bzoj1954】【The xor-longest Path】【trie树】》 给定一棵n个点的带权树,求树上最长的异或和路径

Input

The input contains several test cases. The first line of each test case contains an integer n(1<=n<=100000), The following n-1 lines each contains three integers u(0 <= u < n),v(0 <= v < n),w(0 <= w < 2^31), which means there is an edge between node u and v of length w.

Output

For each test case output the xor-length of the xor-longest path.

Sample Input

4
1 2 3
2 3 4
2 4 6

Sample Output

7

HINT

The xor-longest path is 1->2->3, which has length 7 (=3 ⊕ 4) 
注意:结点下标从1开始到N….

题解:两个点到根的异或和异或一下就是这两个点之间的异或和。

           所以只要统计出所有点到根的异或和,放到trie树里面。

           然后在trie树里面依次查询每个点的最大异或即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100010
using namespace std;
int point[N],next[N<<1],x,y,v,cnt,n,ans,a[N];
struct use{int st,en,v;}e[N<<1];
struct trie{
  int ch[N*30][2],cnt;
  void insert(int x){
    int now(0);
    for (int i=30;i>=0;i--){
      int t=x&(1<<i);t>>=i;
      if (!ch[now][t]) ch[now][t]=++cnt;    
      now=ch[now][t]; 
    }
  }
  int query(int x){
    int now(0),temp(0);
    for (int i=30;i>=0;i--){
      int t=x&(1<<i);t>>=i;
      if (ch[now][t^1]) temp+=1<<i,now=ch[now][t^1];
      else now=ch[now][t];  
    }
    return temp;
  }
}trie;
void add(int x,int y,int v){
  next[++cnt]=point[x];point[x]=cnt;e[cnt].en=y;e[cnt].v=v; 
}
void dfs(int x,int fa){
  for (int i=point[x];i;i=next[i])
   if (e[i].en!=fa){
     a[e[i].en]=a[x]^e[i].v;
     dfs(e[i].en,x);
   }
}
int main(){
  scanf("%d",&n);
  for (int i=1;i<n;i++){
    scanf("%d%d%d",&x,&y,&v);
    add(x,y,v);add(y,x,v);
  } 
  dfs(1,0);
  for (int i=1;i<=n;i++) trie.insert(a[i]);
  for (int i=1;i<=n;i++)
    ans=max(ans,trie.query(a[i]));
  cout<<ans<<endl;
}


    原文作者:Trie树
    原文地址: https://blog.csdn.net/sunshinezff/article/details/51055426
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注