分析
由异或的性质
我们设表示
号节点到根节点路径权值的异或和
所以对于一条树上简单路径
其异或和
那么我们就可以转化题意:
给定个值,求
所以我们可以直接二进制拆分,建立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;
} 
京公网安备 11010502036488号