The XOR-longest Path
题目描述见上面链接
题解:
trie树专题,那么就往这上面想想。
每一条路的路径长度都可以转为二进制用 trie 树存下。
这样的话,我们从头开始,只需比较每次左右 0 和 1 两个儿子都存在,则对答案的贡献则为 1<<w (w 为位置),否则对答案的贡献就为 0 。不得不说真是巧妙啊!
贴代码:
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define M 3100005 4 using namespace std; 5 int ans,n,tot,num,nxt[N*2],w[N*2],to[N*2],hea[N],f[N],trie[M][2]; 6 void insert(int x) 7 { 8 int rt=0,w=30; 9 while (w>=0) 10 { 11 int y=(x>>w) & 1; 12 if (!trie[rt][y]) trie[rt][y]=++num; 13 rt=trie[rt][y]; 14 w--; 15 } 16 } 17 void find(int x) 18 { 19 int sum=0,w=30,rt=0; 20 while (w>=0) 21 { 22 int y=(x>>w) & 1; 23 if (trie[rt][!y]) sum+=1<<w,rt=trie[rt][!y]; 24 else rt=trie[rt][y]; 25 w--; 26 } 27 ans=max(ans,sum); 28 } 29 void add(int x,int y,int z) 30 { 31 nxt[++tot]=hea[x]; hea[x]=tot; w[tot]=z; to[tot]=y; 32 } 33 void dfs(int x,int fa) 34 { 35 find(f[x]); insert(f[x]); 36 for (int j=hea[x]; j; j=nxt[j]) 37 if (to[j]!=fa) f[to[j]]=f[x]^w[j],dfs(to[j],x); 38 } 39 int main() 40 { 41 scanf("%d",&n); 42 for (int i=1,x,y,z; i<n; i++) 43 { 44 scanf("%d%d%d",&x,&y,&z); 45 add(x,y,z); add(y,x,z); 46 } 47 dfs(1,0); 48 printf("%d",ans); 49 return 0; 50 }
加油加油加油!!!fighting fighting fighting!!!