POJ3764 The xor-longest Path(字典树)

The xor-longest Path
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 4946 Accepted: 1076

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:

_{xor}length(p)=\oplus_{e \in p}w(e)

⊕ 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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值