AcWing 144 最长异或值路径(贪心,trie)
解题思路
以任意一个点为根,求出它到根的异或值,那么两个点之间异或值就是两者到根的异或值的异或值(因为重复的数异或值等于0),然后就变成了求n个数中两个数最大的异或值。
代码
const int maxn = 1e6+10;
const int maxm = 3e6+10;
vector<P> e[maxn];
ll d[maxn];
int trie[maxm][2], tot;
void insert(int num) {
int p = 0;
for (int i = 30; i>=0; --i) {
auto &x = trie[p][num>>i&1];
if (!x) x = ++tot;
p = x;
}
}
void dfs(int u, int p) {
for (auto v : e[u])
if (v.second!=p) {
insert(d[v.second]=d[u]^v.first);
dfs(v.second,u);
}
}
ll solve(int num) {
int p = 0; ll res = 0;
for (int i = 30; i>=0; --i) {
res <<= 1;
int x = num>>i&1;
if (trie[p][x^1]) {
res |= 1;
p = trie[p][x^1];
}
else p = trie[p][x];
}
return res;
}
int main() {
int n; scanf("%d",&n);
for (int i = 0; i<n; ++i) {
int u,v,w; scanf("%d%d%d",&u,&v,&w);
e[u].push_back({w,v});
e[v].push_back({w,u});
}
dfs(0,-1);
ll res = 0;
for (int i = 0; i<n; ++i) res = max(res,solve(d[i]));
printf("%lld\n",res);
return 0;
}