trie--- POJ 3764 The xor-longest Path
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 5453 | Accepted: 1190 |
Description
In an edge-weighted tree, the xor-length of a path p is defined as the xor sum of the weights of edges on p:
⊕ is the xor operator.
We say a path the xor-longest path if it has the largest xor-length. Given an edge-weighted tree with n nodes, can you find the xor-longest path?
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
Sample Input
4
0 1 3
1 2 4
1 3 6
Sample Output
7
Hint
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
这道题要求最长的异或路径:就是在树中找两个节点,两个节点间有唯一路径(因为是树),把路径不断做异或,异或完后求最大的。数据是10万,O(n2)算法超时
题目描述:
给你一棵树,n个节点(n = 100000),n-1条边每条边i都有一个权值wi。
定义任意两点间的权值为:
这两点间的路径上的所有边的值的异或。
比如a点和b点间有i,j,k三条边,那么ab两点间的权值为:wi^wj^wk
求这个最大的权值。
/*基本思路:1.因为有(x^z)^(y^z)==x^y,s所以为了求树上任意两点间的x^y的和,我们可以把从根节点开始到每个点的^值存下来(dfs解决,复杂度 O(n)),然后问题就转变为了从这些数中取出两个数字,使他们的异或值最大
如何在剩下的值中寻找两个数的异或和最大,朴素算法n^2,明显是超时的,---经典解决方法:trie树,边建树的同时边搜索匹配,因为是借助trie比较,复杂度就变为了O(nlogn),就可以过了*/
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#define N 100010
struct Edge{/*边表*/
int v,w,last;
}edge[*N];
int head[N]={},t=;
struct Trie{
int next[];
}trie[N<<];/*trie树*/
bool visit[N]={false};
int n,ans=;
int value[N]={},topt=;/*value数组各结点到结点0的异或长度*/
void add_edge(int u,int v,int w)
{
++t;
edge[t].v=v; edge[t].w=w;
edge[t].last=head[u];
head[u]=t;
}
void dfs(int k,int val)
{
visit[k]=true;
value[k]=val;/*dfs求value数组的过程*/
for(int l=head[k];l;l=edge[l].last)
{
if(!visit[edge[l].v])
dfs(edge[l].v,val^edge[l].w);
}
} void add_trie(int num)
{
int now=;/*建trie树的过程*/
for(int i=;i>=;--i)
{
int a=num&(<<i)?:;/*取出num的二进制位的快速方法,注意这里最好用三目运算符解决,我直接用a=num&(1<<i),虽然结果正确,但是在网上提交总是runtime error*/
if(!trie[now].next[a])
trie[now].next[a]=++topt;
now=trie[now].next[a];
}
}
int find(int num)/*从二进制的第31位到第1位查找最大异或值*/
{
int w=;
int now=;
for(int i=;i>=;--i)
{
int a=(num&(<<i))?:;/*获取num的二进制数的第i+1位上的数字的非,这样取出异或值才是最大*/
if(trie[now].next[a])
{
w|=(<<i);
now=trie[now].next[a];
}
else now=trie[now].next[!a]; }
return w;
}
int main()
{
while(scanf("%d",&n)==)
{
int u,v,w;
for(int i=;i<n;++i)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);/*对于每个无向图中,每个节点只走一次,不能只建一条有向边,而是应该建两条边,给每一个节点做一个visit数组即可*/
add_edge(v,u,w);
}
dfs(,);
for(int i=;i<=n-;++i)
{
add_trie(value[i]);/*一边建树*/
int w=;
w=find(value[i]);/*一边查询*/
ans=max(w,ans);
}
printf("%d\n",ans);
memset(head,,sizeof(head));/*对于有多组测试数据的题目,不要忘记每次循环,把所有的量都初始化*/
memset(value,,sizeof(value));
memset(trie,,sizeof(trie));
memset(edge,,sizeof(edge));
memset(visit,,sizeof(visit));
topt=;t=;ans=;n=;
}
return ;
}
trie--- POJ 3764 The xor-longest Path的更多相关文章
- poj3764 The XOR Longest Path【dfs】【Trie树】
The xor-longest Path Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10038 Accepted: ...
- 【POJ 3764】 The xor-longest path
[题目链接] http://poj.org/problem?id=3764 [算法] 首先,我们用Si表示从节点i到根的路径边权异或和 那么,根据异或的性质,我们知道节点u和节点v路径上的边权异或和就 ...
- 【POJ 3764】The Xor-longest Path
题目 给定一个\(n\)个点的带权无根树,求树上异或和最大的一条路径. \(n\le 10^5\) 分析 一个简单的例子 相信大家都做过这题: 给定一个\(n\)个点的带权无根树,有\(m\)个询问, ...
- 题解 bzoj1954【Pku3764 The xor – longest Path】
做该题之前,至少要先会做这道题. 记 \(d[u]\) 表示 \(1\) 到 \(u\) 简单路径的异或和,该数组可以通过一次遍历求得. \(~\) 考虑 \(u\) 到 \(v\) 简单路径的异或和 ...
- poj 3764 The xor-longest Path(字典树)
题目链接:poj 3764 The xor-longest Path 题目大意:给定一棵树,每条边上有一个权值.找出一条路径,使得路径上权值的亦或和最大. 解题思路:dfs一遍,预处理出每一个节点到根 ...
- Solve Longest Path Problem in linear time
We know that the longest path problem for general case belongs to the NP-hard category, so there is ...
- Why longest path problem doesn't have optimal substructure?
We all know that the shortest path problem has optimal substructure. The reasoning is like below: Su ...
- Poj 3764 The xor-longest Path(Trie树+xor+贪心)
The xor-longest Path Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6455 Accepted: 1392 ...
- poj 3764 The xor-longest Path (01 Trie)
链接:http://poj.org/problem?id=3764 题面: The xor-longest Path Time Limit: 2000MS Memory Limit: 65536K ...
- ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)
题目链接:http://poj.org/problem?id=3764 题目大意是在树上求一条路径,使得xor和最大. 由于是在树上,所以两个结点之间应有唯一路径. 而xor(u, v) = xor( ...
随机推荐
- nginx 配置代理某个路径
location /test{ proxy_pass http://localhost:8765/test; proxy_set_header Host $http_host; } 其中红色的那句可以 ...
- perl6正则 3: 行开头与结尾与多行开头,多行结尾
^ $ 匹配一行的开头或结尾, 可以用 ^ 或 $. > so 'abcde' ~~ /e$/ True > so 'abcdef' ~~ /e$/ False > so 'abcd ...
- Ubuntu16.04安装记
Ubuntu16.04安装记 基本信息: 华硕笔记本 Windows 10 家庭版 处理器:Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.71GHz 已安装的内 ...
- libuv 一 环境搭建, hello TTY
引言 - 一时心起, libuv linux 搭建 有一天突然想起来想写个动画. 找了一下 ui 库太大. 后面想起以前弄过的 libuv. 但发现 libuv 相关资料也很少. 所以就有了这些内容. ...
- URL中斜杠/和反斜杠\的区别小结
Unix使用斜杆/ 作为路径分隔符,而web应用最新使用在Unix系统上面,所以目前所有的网络地址都采用 斜杆/ 作为分隔符. Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不 ...
- <转>MYSQL数据库数据拆分之分库分表总结
数据存储演进思路一:单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 数据存储演进思路二:单库多表 随着用户数量的 ...
- bootstrap使用前注意点和盒子模型
bootstrap注意事项: https://getbootstrap.com/docs/4.0/getting-started/introduction/#quick-start 盒子模型: htt ...
- EF – 2.EF数据查询基础(上)查询数据的实用编程技巧
目录 5.4.1 查询符合条件的单条记录 EF使用SingleOrDefault()和Find()两个方法查询符合条件的单条记录. 5.4.2 Entity Framework中的内部数据缓存 DbS ...
- JQuery 分割字符串
JQuery 分割字符串 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- markdown在list或者引用之后怎么去重新令其一段
多打一个空格,虽然这个方法简单的要是,但是我就是没有想到,真是尴尬到奶奶家啦!