1. 程式人生 > >2018.10.26 洛谷P4551 最長異或路徑(01trie)

2018.10.26 洛谷P4551 最長異或路徑(01trie)

傳送門
直接把每個點到根節點的異或距離插入01trie。
然後列舉每個點在01trie上匹配來更新答案就行了。
程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)
)ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans; } const int N=1e5+5; int son[N*32][2],rt=1,n,W,first[N],dis[N],cnt=0,tot=1,ans=0; struct edge{int v,next,w;}e[N<<1]; inline void addedge(int u,int v,int w){e[++cnt].v=v,e[cnt].next=first[u],e[cnt].w=w,first[u]=cnt;} inline void
add(int u,int v,int w){addedge(u,v,w),addedge(v,u,w);} void dfs(int p,int fa,int sum){ dis[p]=sum; for(int i=first[p];i;i=e[i].next){ int v=e[i].v; if(v==fa)continue; dfs(v,p,sum^e[i].w); } } inline void insert(int val){ int p=rt; for(int i=31;~i;--i){ int
tmp=(val>>i)&1; if(!son[p][tmp])son[p][tmp]=++tot; p=son[p][tmp]; } } inline int query(int val){ int ret=0,p=rt; for(int i=31;~i;--i){ int tmp=(val>>i)&1; ret<<=1; if(son[p][tmp^1])++ret,p=son[p][tmp^1]; else p=son[p][tmp]; } return ret; } int main(){ n=read(); for(int i=1,u,v,w;i<n;++i)u=read(),v=read(),w=read(),add(u,v,w); dfs(1,0,0); for(int i=1;i<=n;++i)insert(dis[i]); for(int i=1;i<=n;++i)ans=max(ans,query(dis[i])); printf("%d",ans); return 0; }