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