【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 vof length w.
Output
For each test case output the xor-length of the xor-longest path.Sample Input
41 2 3
2 3 4
2 4 6
Sample Output
7HINT
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; }
相关文章推荐
- R3多线程
- C#冒泡排序法及优化
- java正则表达式
- 导航栏透明度
- android studio 导入一个开源库文件汇总
- Java泛型
- Application.ProcessMessages
- LeetCode 185. Department Top Three Salaries
- yah3c在ubuntu下面的联网之路
- Powerful Incantation(HDU 4150)
- 今天是清明节假期的最后一天
- delphi7的Application.ProcessMessages作用
- solr学习笔记
- Android课程---Android 如何用滑杆(SeekBar)组件设置图片颜色的透明度(转)
- 操作系统的功能、作用、分类
- 操作系统的功能、作用、分类
- 操作系统的功能、作用、分类
- 操作系统的功能、作用、分类
- 操作系统的功能、作用、分类
- 操作系统的功能、作用、分类