The XOR-longest Path
The XOR-longest Path
https://ac.nowcoder.com/acm/problem/50349
分析
由异或的性质
我们设表示
号节点到根节点路径权值的异或和
所以对于一条树上简单路径
其异或和
那么我们就可以转化题意:
给定个值,求
所以我们可以直接二进制拆分,建立01Trie树
贪心走异或最大值
即可
代码
//×Òì»ò·¾¶
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define Cl(X,Y) memset((X),(Y),sizeof(X))
using namespace std;
const int MAXn=1e5+5;
int Total,Next[MAXn<<1],End[MAXn<<1],Head[MAXn],Cur;
int Xor[MAXn],Ans,u,v,w,Val[MAXn<<1],Dfn;
int Trie[MAXn<<5][2];
inline void Add_Edge(int From,int To,int Temp) {
Next[++Cur]=Head[From];
Head[From]=Cur;End[Cur]=To;
Val[Cur]=Temp;
}
inline void DFS(int Temp,int Pre) {
for(int i=Head[Temp];i;i=Next[i]) {
if(End[i]==Pre) continue;
Xor[End[i]]=Xor[Temp]^Val[i];
DFS(End[i],Temp);
}
}
inline void Build_Trie(int Temp,int Root) {
for(int i=1<<30;i;i>>=1) {
bool Jud=Temp & i;
if(!Trie[Root][Jud]) Trie[Root][Jud]=++Dfn;
Root=Trie[Root][Jud];
}
}
inline int Get(int Temp,int Root) {
int Res=0;
for(int i=1<<30;i;i>>=1) {
bool Jud=Temp & i;
if(Trie[Root][Jud ^ 1]) Res+=i,Root=Trie[Root][Jud ^ 1];
else Root=Trie[Root][Jud];
}
return Res;
}
int main() {
scanf("%d",&Total);
for(int i=1;i<Total;i++) {
scanf("%d %d %d",&u,&v,&w);
Add_Edge(u,v,w);Add_Edge(v,u,w);
}
DFS(1,-1);
for(int i=1;i<=Total;i++) Build_Trie(Xor[i],0);
for(int i=1;i<=Total;i++) Ans=max(Ans,Get(Xor[i],0));
cout<<Ans;
return 0;
} 
查看12道真题和解析