1. 程式人生 > WINDOWS開發 >AcWing144 最長異或值路徑 (Trie)

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,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