题意:给出一颗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 ///每个点顶多开32个节点,总共1e5个点。 12 ///如果给出的范围是1e18,那就64个节点 13 int trie[32*maxx][2],cnt; 14 int val[32*maxx]; 15 void add(int u,int v,int w) 16 { 17 e[++tot].to=v,e[tot].val=w; 18 e[tot].next=head[u],head[u]=tot; 19 } 20 void dfs(int u,int fa) //预处理1到各点路径上的异或和 21 { 22 for(int i=head[u];i;i=e[i].next){ 23 int v=e[i].to; 24 if(v==fa) continue; 25 dis[v]=dis[u]^e[i].val; 26 dfs(v,u); 27 } 28 } 29 void Insert(int x) 30 { 31 int rt=0; 32 for(int i=31;i>=0;i--){ 33 int id=(x>>i)&1; 34 if(!trie[rt][id]) 35 trie[rt][id]=++cnt; 36 rt=trie[rt][id]; 37 } 38 val[rt]=x; 39 } 40 int Search(int x) 41 { 42 int rt=0; 43 for(int i=31;i>=0;i--){ 44 int id=(x>>i)&1; 45 if(trie[rt][id^1]) 46 rt=trie[rt][id^1]; 47 else rt=trie[rt][id]; 48 } 49 return val[rt]; 50 } 51 int main() 52 { 53 int n,u,v,w; 54 scanf("%d",&n); 55 for(int i=1;i<n;i++){ 56 scanf("%d%d%d",&u,&v,&w); 57 add(u,v,w);add(v,u,w); 58 } 59 dfs(1,0); 60 for(int i=1;i<=n;i++) 61 Insert(dis[i]); 62 int ans=0; 63 for(int i=1;i<=n;i++) 64 ans=max(ans, dis[i]^Search(dis[i]) ); 65 printf("%d\n",ans); 66 }