一一一一一个问题
查看原帖
一一一一一个问题
1183222
封禁用户楼主2023/11/10 23:53

就是没明白一个地方,最后求ans 题目不是说求x,y之前的吗,但是ans那里不是这个意思啊,是求每个点到跟的,这里面我一定有地方没搞明白,求助一下

//P4551 最长异或路径

/*
题目: 求树上两个点之间边的最大异或和 

字典树;
	思路: dfs一次处理dis数组,dis[i]表示i节点到根节点的边权异或和
			因为x异或x = 0
			所以dis[u] ^ dis[v] 就可以表示u和b到lca的异或和
		   最后字典树查询dis最大值就行		 
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000006;
int tire[maxn][2];
struct node{
	int to;
	int len;
	int next;
}G[maxn] ;

int cnt, n;
int head[maxn];

void add(int u, int v, int len){
	++cnt;
	G[cnt].to = v;
	G[cnt].len = len;
	G[cnt].next = head[u];
	head[u] = cnt;
}

int dis[maxn];

void dfs(int u, int fa){
	for (int i = head[u]; i; i = G[i].next){
		int v = G[i].to;
		int w = G[i].len;
		if (v != fa){
			dis[v] = dis[u] ^ w;
			dfs(v, u);
		}
	}
}

//以每个点到跟的异或和建立字典树
int tot;
void insert(int x){
	int p = 0;
	for (int i = 30; i >= 0; i--){
		if (tire[p][(x>>i) & 1] == 0 ){
			tire[p][(x>>i) & 1] = ++tot;
		}
		p = tire[p][(x>>i) & 1];
	}
} 

int find(int x) {
	int p = 0;
	int res = 0;
	for (int i = 30; i >= 0; i--){
		res = res << 1;
		int k = (x >> i) & 1;
		k = k ^ 1;
		if (tire[p][k] != 0){
			res++;
			p = tire[p][k];
		}else {
			p = tire[p][k^1];
		}
	}
	return res;
}

int main () {
	cin >> n;
	for (int i = 1; i < n; i++){
		int u, v, len;
		cin >> u >> v >> len;
		add(u, v, len);
		add(v, u, len);
	}
	
	dis[1] = 0;
	dfs(1, 0);
	
	for (int i = 1;i <= n; i++ ){
		insert(dis[i]);
	}
	
	int ans = 0;
	for (int i = 1;i <= n;i++){
		ans = max (ans, find(dis[i]) ) ;
	}
	cout << ans;
	return 0;
	
}

2023/11/10 23:53
加载中...