P4551 最长异或路径

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4551 最长异或路径相关的知识,希望对你有一定的参考价值。

P4551 最长异或路径

题意:

给定一棵 n 个点的带权树,结点下标从 1 开始到 n。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或。

题解:

我们指定1为根节点,T(u,v)表示u到v之间的路径的边权异或和,那么T(u,v)=T(root,u) Xor T(root,v)
所以我们可以将所有的T(root,u)插入到一个trie中,对每个T(root,u)快速求出和它异或最大的T(root,v)
从trie的根开始,如果能向和T(root,u)的当前位不同的子树走,就向那边走,否则没有选择

代码:

#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\\n",a,b);
typedef long long ll;
using namespace std;
//Fe~Jozky
const ll INF_ll=1e18;
const int INF_int=0x3f3f3f3f;
inline ll read(){
   ll s=0,w=1ll;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=3e5+9;
int rtnum=1;
struct tree_01{
	int cnt;
	int ch[2];
	void init(){
		ch[0]=ch[1]=0;
		cnt=0;
	} 
}tr[maxn<<4];
vector<pair<int,int> >vec[maxn];
int ans=0;
int dis[maxn];
void insert(int x){
	int rt=1;
	
	for(int i=30;i>=0;i--){
		int c=((x>>i)&1);
		if(tr[rt].ch[c]==0)
		{
			tr[rt].ch[c]=++rtnum;
			
		//	tr[rtnum].init();
		}
		rt=tr[rt].ch[c];
	}
}
void get(int x){
	int rt=1;
	int cnt=0;
	for(int i=30;i>=0;i--){
		int c=((x>>i)&1);
		if(tr[rt].ch[c^1]){
			rt=tr[rt].ch[c^1];
			cnt|=(1<<i);
		}
		else if(tr[rt].ch[c])rt=tr[rt].ch[c];
		else break ;
	}
	ans=max(ans,cnt);
}
void dfs(int x,int fa){
	insert(dis[x]);
	get(dis[x]);
	
	for(auto it:vec[x]){
		int v=it.first;
		int w=it.second;
		if(v==fa)continue;
		dis[v]=dis[x]^w;
		dfs(v,x);
	}
	return ;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v,w;
		cin>>u>>v>>w;
		vec[u].push_back({v,w});
		vec[v].push_back({u,w});
	}
	tr[1].init();
	dis[1]=0;
	dfs(1,0);
	cout<<ans;

}


以上是关于P4551 最长异或路径的主要内容,如果未能解决你的问题,请参考以下文章

[luogu] P4551 最长异或路径(贪心)

洛谷 P4551 最长异或路径

P4551 最长异或路径

P4551 最长异或路径(01trie模板)

P4551 最长异或路径

P4551 最长异或路径