[Ybtoj第9章例3]最長のXORパス[トライツリー]

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入


問題解決のアイデア

パスの排他的論理和の計算方法を検討してください。2つの同じ数の排他的論理和の値は0であることがわかっています。

レッツS [i]は、S [i]はs [ i ]は、ポイントiiへのルートノードを表しますiのXOR値、次にポイントlllからrr指すr間のパスのXOR値はsls_lです。sリットル xor xor x o r sr s_rsR、したがって、最初にs配列を前処理すると、答えはmaxmaxになります。m a x si s_is xor xor x o r sj s_jsJ (1 <= i <j <= n)(1 <= i <j <= n) 1<=<j<=n 、この質問は前の質問と同等です-最大のXORペア


コード

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

int n,k,s[3200010],trie[3200010][2],h[200010],tot=1,u,v,w,ans;

struct c{
    
    
	int x,next,w;
}a[200010]; 

void add(int x,int y,int w)//建邻接表
{
    
    
	k++;
	a[k].x=y;
	a[k].next=h[x];
	a[k].w=w;
	h[x]=k;
}

void dfs(int x,int fa){
    
    //求出所有的s[i]
	int v;
	for(int i=h[x];i;i=a[i].next)
	{
    
    
		v=a[i].x;
		if(v==fa)continue;
		s[v]=s[x]^a[i].w;
		dfs(v,x);
	}
}

int get(int x){
    
    
	int p=1,ans=0,c;
	for(int i=31;i>=0;i--)
	{
    
    
		if(((x>>i)&1)==1)
			c=0;
		else c=1;
		if(trie[p][c])
			ans+=(1<<i);
		else c=(x>>i)&1;
		p=trie[p][c];
	}
	return ans;
}

void insert(int x){
    
    
	int p=1,c;
	for(int i=31;i>=0;i--)
	{
    
    
		c=(x>>i)&1;
		if(!trie[p][c])
			trie[p][c]=++tot;
		p=trie[p][c];
	}
}

int main(){
    
    
	scanf("%d",&n);
	for(int i=1;i<=n-1;i++)
	{
    
    
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
	}
	dfs(1,0);
	//后面的就跟上一题(最大异或对)一样了
	for(int i=1;i<=n;i++)
		insert(s[i]);
	for(int i=1;i<=n;i++)
		ans=max(ans,get(s[i]));
	printf("%d",ans);
}

おすすめ

転載: blog.csdn.net/kejin2019/article/details/115019815