AcWing144 最长异或值路径 (Trie)

简单的贪心Trie思路,只要发现异或和路径就是两个到根节点的路径的异或值就行,之后Trie树贪心

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,pair<int,int> > plll;
const int N=3e5+10;
const int inf=0x3f3f3f3f;
int tr[3000001][2];
int h[N],ne[N],e[N],w[N],idx;
int cnt;
int sum[N];
void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void dfs(int u,int res,int fa){
    int i;
    sum[u]=res;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
        continue;
        int c=w[i];
        dfs(j,res^c,u);
    }
}
void insert(int x){
    int i;
    int cur=0;
    for(i=30;i>=0;i--){
        int num=x>>i&1;
        if(tr[cur][num]==0)
        tr[cur][num]=++cnt;
        cur=tr[cur][num];
    }
}
int search(int x){
    int cur=0;
    int i;
    int res=0;
    for(i=30;i>=0;i--){
        int num=x>>i&1;
        if(tr[cur][num^1]){
            res+=1<<i;
            cur=tr[cur][num^1];
        }
        else{
            cur=tr[cur][num];
        }
    }
    return res;
}
int main(){
    memset(h,-1,sizeof h);
    int n;
    cin>>n;
    int i;
    for(i=1;i<n;i++){
        int u,v,c;
        scanf("%d%d%d",&u,&v,&c);
        add(u,v,c);
        add(v,u,c);
    }
    dfs(1,0,-1);
    for(i=0;i<n;i++){
        insert(sum[i]);
    }
    int res=0;
    for(i=0;i<n;i++){
        res=max(res,search(sum[i]));
    }
    cout<<res<<endl;
}
View Code

猜你喜欢

转载自www.cnblogs.com/ctyakwf/p/12676772.html