题目链接在这里:P4551 最长异或路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
是一道比较经典的问题,对于异或问题经常会使用01trie树来解决。
当然01trie树只是用来统计答案,往往还需要一些预处理操作。
比如此题需要把从当前点到根节点的路径的异或和求出来,讨论与根节点的联系在树的问题中很常见。
1 #include "bits/stdc++.h" 2 using namespace std; 3 const int MAX=1e6+5; 4 int n; 5 int tot,head[MAX],adj[MAX],nxt[MAX],wei[MAX]; 6 int val[MAX]; 7 void addedge(int u,int v,int w){ 8 tot++; 9 adj[tot]=v; 10 wei[tot]=w; 11 nxt[tot]=head[u]; 12 head[u]=tot; 13 } 14 void dfs(int x,int fa){ 15 int i,j; 16 for (i=head[x];i;i=nxt[i]){ 17 if (adj[i]==fa) continue; 18 val[adj[i]]=val[x]^wei[i]; 19 dfs(adj[i],x); 20 } 21 } 22 struct Str{ 23 int str[MAX][2],cnt; 24 bool vis[MAX]; 25 Str(){ 26 memset(str,0,sizeof(str)); 27 cnt=0; 28 memset(vis,false,sizeof(vis)); 29 } 30 void insert(int x){ 31 int i,j,p=0; 32 bool zt; 33 for (i=30;i>=0;i--){ 34 zt=(1<<i)&x; 35 if (str[p][zt]==0){ 36 str[p][zt]=++cnt; 37 p=cnt; 38 } 39 else p=str[p][zt]; 40 } 41 vis[p]=true; 42 } 43 int check(int v){ 44 int i,j,p=0,ans=0; 45 bool zt; 46 for (i=30;i>=0;i--){ 47 zt=v&(1<<i); 48 if (str[p][!zt]){ 49 ans+=(1<<i); 50 p=str[p][!zt]; 51 } 52 else p=str[p][zt]; 53 // cout<<p<<endl; 54 } 55 // cout<<v<<' '<<ans<<endl; 56 return ans; 57 } 58 }ss; 59 int main(){ 60 int i,j,u,v,w,ans=0; 61 scanf("%d",&n); 62 memset(head,0,sizeof(head)); 63 memset(val,0,sizeof(val)); 64 for (i=1;i<n;i++){ 65 scanf("%d%d%d",&u,&v,&w); 66 addedge(u,v,w); 67 addedge(v,u,w); 68 } 69 dfs(1,0); 70 // for (i=1;i<=n;i++) 71 // cout<<i<<" : "<<val[i]<<endl; 72 for (i=1;i<=n;i++) 73 ss.insert(val[i]); 74 for (i=1;i<=n;i++) 75 ans=max(ans,ss.check(val[i])); 76 printf("%d\n",ans); 77 return 0; 78 }
标签:head,抑或,int,MAX,01trie,tot,字符串,adj From: https://www.cnblogs.com/keximeiruguo/p/16902573.html