AcWing144 longest XOR value path (Trie)

The simple greedy Trie idea, as long as the XOR path is found to be the XOR value of the two paths to the root node, then the Trie tree is greedy

#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

 

Guess you like

Origin www.cnblogs.com/ctyakwf/p/12676772.html