Xor Tree CodeForces - 1446C

原题链接
考察: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;
}
posted @ 2021-06-06 22:53  acmloser  阅读(54)  评论(0编辑  收藏  举报