最长异或路径(dfs+01trie)

该博客介绍了如何运用深度优先搜索(DFS)和01 Trie数据结构来解决图中两点间最大异或距离的问题。首先通过DFS计算从节点1到所有节点的异或路径值,然后利用01 Trie存储这些值并寻找最大异或值。通过这个方法,可以高效地找出图中任意两点的最大异或路径长度。
摘要由CSDN通过智能技术生成

最长异或路径 - 洛谷https://www.luogu.com.cn/problem/P4551先用dfs把节点1到所有点的异或路径值求出来,根据异或性质可以得出任意两点得异或距离,此时问题为求两点最大异或距离,可以转化为给一个数求一个序列中其最大异或值,就可以用01trie来写了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
using ll = long long;
using ull = unsigned long long;
using P = pair<int,int>;
using pll=pair<ll,ll>;
const int MAXN=1e6+5;
const int INF=0x3f3f3f3f;
const ll NNF=0x3f3f3f3f3f3f3f3f;
const int MAXBIT=31;

int n;
int head[MAXN];
int ver[MAXN];
int cost[MAXN];
int num[MAXN];
int nxt[MAXN];
int tri[MAXN][2];
int rec=1;
int cnt;
void add(int x,int y,int c){
	ver[++cnt]=y;
	cost[cnt]=c;
	nxt[cnt]=head[x];
	head[x]=cnt;
}
int d[MAXN];
void dfs(int p,int fa){
//	printf("===\n");
	for(int i=head[p];i;i=nxt[i]){
		int v=ver[i];
		if(v==fa) continue;
		d[v]=d[p]^cost[i];
		dfs(v,p);
	}
}

void insert(int x){
	int cur=1;
	for(int i=MAXBIT;i>=0;i--){
		int bit=x>>i&1;
		if(!tri[cur][bit]) tri[cur][bit]=++rec;
		cur=tri[cur][bit];
	}
	num[cur]=x;
}

int find_max(int x){
	int cur=1;
	for(int i=MAXBIT;i>=0;i--){
		int bit=x>>i&1;
		if(tri[cur][bit^1]) cur=tri[cur][bit^1];
		else cur=tri[cur][bit];
	}
	return x^num[cur];
}

int main(){
	scanf("%d",&n);
	int x,y,c;
	for(int i=1;i<n;i++){
		scanf("%d %d %d",&x,&y,&c);
		add(x,y,c);
		add(y,x,c);
	}
	dfs(1,-1);
	for(int i=1;i<=n;i++){
		insert(d[i]);
	}
	int mx=0;
	for(int i=1;i<=n;i++){
		mx=max(mx,find_max(d[i]));
	}
	printf("%d",mx);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值