您的位置:首页 > 其它

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

2016-04-04 10:21 447 查看

Description


 给定一棵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
,next[N<<1],x,y,v,cnt,n,ans,a
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: