[Trie树]C. 【例题3】最长异或路径


解析

这道题我觉得恶心的地方就是要求一整条边的边权的异或给搞出来, 注意运算符不要用错了。

Code

#include <bits/stdc++.h>
#define N 100005
using namespace std;

struct node
{
	int x, to, nxt;
}hd[N * 2];
struct Trie 
{
	int son [2];
}trie[1000001];
int tr[N];
int n, x, y, z, go, tag, tagg, ans;

void add (int x, int y, int z)
{
	hd[++ tag] = {z, y, tr[x]}; 
	tr[x] = tag;
	hd[++ tag] = {z, x, tr[y]};
	tr[y] = tag;
}

void build (int num)
{
	int now = 0;
	for (int i = 31; i >= 0; -- i)
	{
		go = num >> i & 1;
		if (!trie[now].son[go]) trie[now].son[go] = ++ tagg;
		now = trie[now].son[go];
	}
}

int find (int num)
{
	int now = 0, re = 0;
	for (int i = 31; i >= 0; -- i)
	{
		go = num >> i & 1;
		if (trie[now].son[go ^ 1])
		{
			now = trie[now].son[go ^ 1];
			re |= 1 << i;
		}
		else if (trie[now].son[go]) now = trie[now].son[go];
		else return re;
	}
	return re;
}

void dfs1 (int now, int father, int num)
{
	build (num);
	for (int i = tr[now]; i; i = hd[i].nxt)
	{
		if (hd[i].to != father)
		 dfs1 (hd[i].to, now, num ^ hd[i].x);
	}
	
}

void dfs2 (int now, int father, int num)
{
	ans = max (ans, find (num));
	for (int i = tr[now]; i; i = hd[i].nxt)
	{
		if (hd[i].to != father)
		 dfs2(hd[i].to, now, num ^ hd[i].x);	
	} 
}

int main ()
{
	scanf ("%d", &n);
	for (int i = 1; i < n; ++ i)
	{
		scanf ("%d%d%d", &x, &y, &z);
		add (x, y, z);
	}
	dfs1 (1, 0, 0);
	dfs2 (1, 0, 0);
	printf ("%d", ans);
	return 0;
}```
posted @ 2021-06-12 20:51  unknown_future  阅读(64)  评论(0编辑  收藏  举报