过程
手写利用DFS求出每个点到根节点的异或距离
不难得出
xor_dis[x][y]=xor_dis[0][x]^xor_dis[0][y]
于是树上异或问题转换成了Trie上异或问题。
代码
直接看代码吧,注释很全
#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e6+128;
namespace G
{
struct Edge
{
int to;
int next;
unsigned int val;
} egde[N];
int deg=0;
int head[N];
inline void add_edge(int from,int to,unsigned int val)
{
egde[++deg].next=head[from];
egde[deg].to=to;
egde[deg].val=val;
head[from]=deg;
}
unsigned int dis[N]; // 用来表示 1 节点到 n 节点 xor路径
void dfs(int x,unsigned int val)
{
dis[x]=val;
for(int i=head[x]; i!=0; i=egde[i].next)
dfs(egde[i].to,val^egde[i].val);
}
}
namespace trie
{
struct Node
{
Node * next[2];
} trie[N];
int m;
inline Node * NEW()
{
return &trie[m++];
}
inline int getbit(unsigned int val,int addr)
{
return (val>>(addr-1))&1;
}
void insert(unsigned int val,int n,Node * trie_node)
{
if(n==0)
return ;
int c=getbit(val,n);
if(trie_node->next[c]==NULL)
trie_node->next[c]=NEW();
insert(val,n-1,trie_node->next[c]);
}
void FindMaxVal(unsigned int &buffer_num,int n,Node * trie_node)
{
if(n==0)
return ;
int c=getbit(buffer_num,n);
if(trie_node->next[c^1]!=NULL) //c^1 该位为1
{
buffer_num|=1<<(n-1);
FindMaxVal(buffer_num,n-1,trie_node->next[c^1]);
} else { // 为 0
buffer_num^=c<<(n-1); //c=c^c==0
FindMaxVal(buffer_num,n-1,trie_node->next[c]);
}
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<n; i++) //n个点只有 n-1条边
{
int u,v;
unsigned w;
scanf(" %d %d %u",&u,&v,&w);
G::add_edge(u,v,w);
}
G::dfs(1,0);
trie::NEW();
for(int i=1;i<=n;i++)
trie::insert(G::dis[i],32,&trie::trie[0]);
unsigned int maxn=0;
//这里有个重要结论 xor_dis[x][y]=xor_dis[0][x]^xor_dis[0][y];
for(int i=1;i<=n;i++)
{
unsigned int t=G::dis[i];
trie::FindMaxVal(t,32,&trie::trie[0]);
maxn=max(maxn,t);
}
printf("%u",maxn);
}