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;
}
全部评论

相关推荐

拉丁是我干掉的:把上海理工大学改成北京理工大学。成功率增加200%
点赞 评论 收藏
分享
1 3 评论
分享
牛客网
牛客企业服务