最长异或路径java_最长异或值路径

给定一个树,树上的边都具有权值。

树中一条路径的异或长度被定义为路径上所有边的权值的异或和:

9e79f80b46fee3970304ae4014af8e4e.png

⊕ 为异或符号。

给定上述的具有n个节点的树,你能找到异或长度最大的路径吗?

输入格式

第一行包含整数n,表示树的节点数目。

接下来n-1行,每行包括三个整数u,v,w,表示节点u和节点v之间有一条边权重为w。

输出格式

输出一个整数,表示异或长度最大的路径的最大异或和。

数据范围

1≤n≤100000

0≤u,v

0≤w<2^31输入样例:

4

0 1 3

1 2 4

1 3 6

输出样例:

7

样例解释

样例中最长异或值路径应为0->1->2,值为7 (3 ⊕ 4)

考虑,这样一个树结构,如果0是根,有0- > 1- > 2- >3,就是0到1的权值异或和异或1到3的异或和,再去掉多余部分,多余部分多了两次,而a ^ a = 0,0 ^ a = a,因此求每一个节点到根的异或和,求1到3的异或和让1到根和3到根的异或和异或一下即可

#include

using namespace std;

const int N = 1e5 + 10;

int head[N * 2], nex[N * 2], cnt;

struct p{

int to, dist;

p(){}

p(int to, int dist){this->to = to;this->dist = dist;}

};

p g[N * 2];

int aa[N];

void add(int a, int b, int c){

g[++cnt].to = b;

g[cnt].dist = c;

nex[cnt] = head[a];

head[a] = cnt;

}

void dfs(int ind, int father, int sum){

aa[ind] = sum;

for (int j = head[ind]; ~j; j = nex[j]){

if(g[j].to != father){

dfs(g[j].to, ind, sum ^ g[j].dist);

}

}

}

int trie[N * 32][2], tot = 1;

void insert(int Number){

int p = 1;

for (int i = 31; i >= 0; i--){

int t = (Number >> i) & 1;

if(!trie[p][t])trie[p][t] = ++tot;

p = trie[p][t];

}

}

int search(int Number){

int p = 1;

int res = 0;

for (int i = 31; i >= 0; i--){

int t = (Number >> i) & 1;

if(t == 1){

if(trie[p][0]){

p = trie[p][0];

res += (1 << i);

}

else p = trie[p][1];

}

else if(t == 0){

if(trie[p][1]){

p = trie[p][1];

res += (1 << i);

}

else p = trie[p][0];

}

}

return res;

}

int main()

{

int n;

scanf("%d", &n);

memset(head, -1, sizeof head);

memset(nex, -1, sizeof nex);

for (int i = 1; i < n; i++){

int a, b, c;

scanf("%d %d %d", &a, &b, &c);

add(a, b, c);

add(b, a, c);

}

dfs(0, -1, 0);

for (int i = 0; i < n; i++){

insert(aa[i]);

}

int res = 0;

for (int i = 0; i < n; i++){

res = max(res, search(aa[i]));

}

printf("%d\n", res);

return 0;

}

长时间不用邻接表,生疏了,,,,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值