题意:给出一颗n个节点的数,节点之间的边有权值,求任意两个节点之间的最大异或值
思路:我们将整个图走一遍dfs,求出节点1到其他所有节点的异或值,用数组dis来储存
然后接下来求任意两个节点之间的路径异或值,就是dis【x】^dis【y】
所以我们接下来就用每一个点来遍历一次图,枚举更新最大值即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxx = 1e5+10; 4 struct node 5 { 6 int to,val,next; 7 }e[2*maxx]; 8 int head[maxx],tot; 9 int dis[maxx]; 10 ///最多不超过32*maxx个节点 11 int trie[32*maxx][2],cnt; 12 int val[32*maxx]; 13 void add(int u,int v,int w) 14 { 15 e[++tot].to=v,e[tot].val=w; 16 e[tot].next=head[u],head[u]=tot; 17 } 18 void dfs(int u,int fa) //预处理1到各点路径上的异或和 19 { 20 for(int i=head[u];i;i=e[i].next){ 21 int v=e[i].to; 22 if(v==fa)continue; 23 dis[v]=dis[u]^e[i].val; 24 dfs(v,u); 25 } 26 } 27 void Insert(int x) 28 { 29 int rt=0; 30 for(int i=31;i>=0;i--){ 31 int id=(x>>i)&1; 32 if(!trie[rt][id])trie[rt][id]=++cnt; 33 rt=trie[rt][id]; 34 } 35 val[rt]=x; 36 } 37 int Search(int x) 38 { 39 int rt=0; 40 for(int i=31;i>=0;i--){ 41 int id=(x>>i)&1; 42 if(trie[rt][id^1])rt=trie[rt][id^1]; 43 else rt=trie[rt][id]; 44 } 45 return val[rt]; 46 } 47 int main() 48 { 49 int n,u,v,w; 50 scanf("%d",&n); 51 for(int i=1;i<n;i++){ 52 scanf("%d%d%d",&u,&v,&w); 53 add(u,v,w);add(v,u,w); 54 } 55 dfs(1,0); 56 for(int i=1;i<=n;i++)Insert(dis[i]); 57 int ans=0; 58 for(int i=1;i<=n;i++) ans=max(ans, dis[i]^Search(dis[i]) ); 59 printf("%d\n",ans); 60 }
原文:https://www.cnblogs.com/pangbi/p/12403921.html