POJ3764 The xor-longest Path(字典树)
2015-11-17 10:35
405 查看
The xor-longest Path
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
For each test case output the xor-length of the xor-longest path.
Sample Input
Sample Output
Hint
The xor-longest path is 0->1->2, which has length 7 (=3 ⊕ 4)
题目链接: 点击打开链接
给出n节点的权值, 问你最大异或值为多少.
建立字典树, 根据异或运算的性质, 两节点的异或值等于这条路的两节点间的连续异或值, 树的节点记录根节点到该点的连续异或值.
将节点插入字典树, 然后dfs遍历寻找最大值.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e5 + 5;
struct node
{
/* data */
int from, to, nxt, val;
}edge[MAXN << 1];
int n, v, ans, cnt, size;
int head[MAXN], dis[MAXN], nxt[MAXN * 30][2];
void add(int from, int to, int val)
{
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].val = val;
edge[cnt].nxt = head[from];
head[from] = cnt++;
}
void dfs(int x, int f, int d)
{
dis[x] = d;
for(int i = head[x]; i != -1; i = edge[i].nxt)
if((v = edge[i].to) != f) dfs(v, x, d ^ edge[i].val);
}
int new_node()
{
memset(nxt[size], 0, sizeof(nxt[size]));
return size++;
}
void insert(int x)
{
int p = 0, index;
for(int i = 31; i >= 0; --i) {
index = x & (1ll << i) ? 1 : 0;
if(!nxt[p][index]) nxt[p][index] = new_node();
p = nxt[p][index];
}
}
void find(int x)
{
int p = 0, w = 0, index;
for(int i = 31; i >= 0; --i) {
index = x & (1ll << i) ? 0 : 1;
if(nxt[p][index]) {
w |= 1ll << i;
p = nxt[p][index];
}
else p = nxt[p][!index];
}
ans = max(ans, w);
}
int main(int argc, char const *argv[])
{
while(scanf("%d", &n) != EOF) {
memset(head, -1, sizeof(head));
memset(nxt, 0, sizeof(nxt));
memset(dis, 0, sizeof(dis));
ans = -1, cnt = 1, size = 1;
for(int i = 1; i < n; ++i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
a++, b++;
add(a, b, c), add(b, a, c);
}
dfs(1, 0, 0);
for(int i = 1; i <= n; ++i) {
insert(dis[i]);
find(dis[i]);
}
printf("%d\n", ans);
}
return 0;
}
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 4946 | Accepted: 1076 |
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
For each test case output the xor-length of the xor-longest path.
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)
题目链接: 点击打开链接
给出n节点的权值, 问你最大异或值为多少.
建立字典树, 根据异或运算的性质, 两节点的异或值等于这条路的两节点间的连续异或值, 树的节点记录根节点到该点的连续异或值.
将节点插入字典树, 然后dfs遍历寻找最大值.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e5 + 5;
struct node
{
/* data */
int from, to, nxt, val;
}edge[MAXN << 1];
int n, v, ans, cnt, size;
int head[MAXN], dis[MAXN], nxt[MAXN * 30][2];
void add(int from, int to, int val)
{
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].val = val;
edge[cnt].nxt = head[from];
head[from] = cnt++;
}
void dfs(int x, int f, int d)
{
dis[x] = d;
for(int i = head[x]; i != -1; i = edge[i].nxt)
if((v = edge[i].to) != f) dfs(v, x, d ^ edge[i].val);
}
int new_node()
{
memset(nxt[size], 0, sizeof(nxt[size]));
return size++;
}
void insert(int x)
{
int p = 0, index;
for(int i = 31; i >= 0; --i) {
index = x & (1ll << i) ? 1 : 0;
if(!nxt[p][index]) nxt[p][index] = new_node();
p = nxt[p][index];
}
}
void find(int x)
{
int p = 0, w = 0, index;
for(int i = 31; i >= 0; --i) {
index = x & (1ll << i) ? 0 : 1;
if(nxt[p][index]) {
w |= 1ll << i;
p = nxt[p][index];
}
else p = nxt[p][!index];
}
ans = max(ans, w);
}
int main(int argc, char const *argv[])
{
while(scanf("%d", &n) != EOF) {
memset(head, -1, sizeof(head));
memset(nxt, 0, sizeof(nxt));
memset(dis, 0, sizeof(dis));
ans = -1, cnt = 1, size = 1;
for(int i = 1; i < n; ++i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
a++, b++;
add(a, b, c), add(b, a, c);
}
dfs(1, 0, 0);
for(int i = 1; i <= n; ++i) {
insert(dis[i]);
find(dis[i]);
}
printf("%d\n", ans);
}
return 0;
}
相关文章推荐
- 装饰者模式在Java 字节输入流中的应用
- 【Java并发编程】之二十一:并发新特性—阻塞队列和阻塞栈(含代码)
- linux sed 批量替换字符串
- ivrdemo_读取xml
- mysqlscript文档翻译
- Android_ScrollView子控件是否在展示中
- Hibernate之Session的创建
- Android 获取屏幕宽高
- 高清ICON SVG解决方案
- Map 循环
- docker index服务概述
- Android开发技巧——自定义控件之组合控件
- FPGA的latch总结
- win8电脑启动后黑屏怎么办 win8启动黑屏的解决方法
- Android开发技巧——自定义控件之组合控件
- Linux运维利器之ClusterShell
- docker index服务概述
- 分布式事务
- MYSQL一些常用的命令
- simple data 安装和使用记录