最长异或路径 - 洛谷https://www.luogu.com.cn/problem/P4551先用dfs把节点1到所有点的异或路径值求出来,根据异或性质可以得出任意两点得异或距离,此时问题为求两点最大异或距离,可以转化为给一个数求一个序列中其最大异或值,就可以用01trie来写了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int,int>;
using pll=pair<ll,ll>;
const int MAXN=1e6+5;
const int INF=0x3f3f3f3f;
const ll NNF=0x3f3f3f3f3f3f3f3f;
const int MAXBIT=31;
int n;
int head[MAXN];
int ver[MAXN];
int cost[MAXN];
int num[MAXN];
int nxt[MAXN];
int tri[MAXN][2];
int rec=1;
int cnt;
void add(int x,int y,int c){
ver[++cnt]=y;
cost[cnt]=c;
nxt[cnt]=head[x];
head[x]=cnt;
}
int d[MAXN];
void dfs(int p,int fa){
// printf("===\n");
for(int i=head[p];i;i=nxt[i]){
int v=ver[i];
if(v==fa) continue;
d[v]=d[p]^cost[i];
dfs(v,p);
}
}
void insert(int x){
int cur=1;
for(int i=MAXBIT;i>=0;i--){
int bit=x>>i&1;
if(!tri[cur][bit]) tri[cur][bit]=++rec;
cur=tri[cur][bit];
}
num[cur]=x;
}
int find_max(int x){
int cur=1;
for(int i=MAXBIT;i>=0;i--){
int bit=x>>i&1;
if(tri[cur][bit^1]) cur=tri[cur][bit^1];
else cur=tri[cur][bit];
}
return x^num[cur];
}
int main(){
scanf("%d",&n);
int x,y,c;
for(int i=1;i<n;i++){
scanf("%d %d %d",&x,&y,&c);
add(x,y,c);
add(y,x,c);
}
dfs(1,-1);
for(int i=1;i<=n;i++){
insert(d[i]);
}
int mx=0;
for(int i=1;i<=n;i++){
mx=max(mx,find_max(d[i]));
}
printf("%d",mx);
return 0;
}