1. 程式人生 > >POJ 3764 The xor-longest Path 01字典樹+dfs

POJ 3764 The xor-longest Path 01字典樹+dfs

題目連結

題意

給定一顆樹,要求找出一條路徑,其邊的權值異或和最大。

思路

求出各節點到根的異或和,假設兩結點u,v到根的異或和為a[u],a[v] 那麼u到v的異或和為a[u]^a[v] ,u,v的lca到根因為重複被去掉了。插入字典樹中查詢就行了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<queue>
#include<stack> #include<set> #include<map> #define ll long long using namespace std; const int INF = ( 2e9 ) + 2; const ll maxn = 1e5+100; struct edge { int v,w,next; }e[maxn*3]; int head[maxn]; int tot,tot1,ans; int t[maxn*33][2]; void add(int u,int v,int w) { e[tot].v=v; e[tot].w=w; e[tot].next=head[u]; head[u]=tot++; } void
init() { memset(head,-1,sizeof(head)); tot=tot1=0; t[0][0]=t[0][1]=0; ans=0; } void insert(int rt,int st,int a) { if(st==-1)return; int cur=(a>>st)&1; if(!t[rt][cur])t[rt][cur]=++tot1,t[tot1][1]=0,t[tot1][0]=0; insert(t[rt][cur],st-1,a); } int find(int rt,int st,int
a) { if(st==-1)return 0; int cur=(a>>st)&1; if(t[rt][cur^1])return (1<<st) + find(t[rt][cur^1],st-1,a); else return find(t[rt][cur],st-1,a); } void dfs(int u,int fa,int a) { insert(0,31,a); for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v,w=e[i].w; if(v==fa)continue; ans=max(ans,find(0,31,a^w)); dfs(v,u,a^w); } } int main() { int n,u,v,w; while(~scanf("%d",&n)) { init(); for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } dfs(1,-1,0); printf("%d\n",ans); } }