[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;
}```