菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
5
0

Xor Tree CodeForces - 1446C

原创
05/13 14:22
阅读数 31755

原题链接
考察:Trie+dfs
思路:
  将每个数插入Trie中,可以发现如果子树的结点>=2,那么这些结点会内部连接,也就是说:如果左子树和右子树的结点都>=2,那么它们就是割裂的,我们需要删除一些点使得它们连接.
  最少删除数 = 最大保留数.对于当前树u, 最大保留数
:f[u] =max(f[左],f[右])+1,如果我们要保证连接左子树和右子树有一个只能保存一个结点,所以是保留最大结点数+1.

Code

#include <iostream> 
#include <cstring>
using namespace std;
const int N = 200010;
int son[N*32][2],idx,n;
void insert(int x)
{
	int p = 0;
	for(int i=31;i>=0;i--)
	{
		int a = x>>i&1;
		if(!son[p][a]) son[p][a] = ++idx;
		p = son[p][a];
	}
}
int dfs(int u)
{
	if(!son[u][0]&&!son[u][1]) return 1;//叶子节点
	if(!son[u][0]) return dfs(son[u][1]);
	if(!son[u][1]) return dfs(son[u][0]);
	return max(dfs(son[u][1]),dfs(son[u][0]))+1;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		insert(x);
	}
	printf("%d\n",n-dfs(0));
	return 0;
}

发表评论

0/200
5 点赞
0 评论
收藏
为你推荐 换一批