Codeforces 1447E. Xor Tree(字典树/贪心)

博客详细解析了Codeforces Round #683 (Div. 2) 比赛中E题XorTree的问题。题目要求确定数组中需要删除的最少元素数量,使得形成的图是一棵树。作者通过建立01字典树,利用贪心策略解决了问题。AC代码使用C++编写,实现了根据异或关系构建连通块并判断是否为树的算法。
摘要由CSDN通过智能技术生成

Codeforces Round #683 (Div. 2, by Meet IT) 全文见:https://blog.csdn.net/qq_43461168/article/details/113175011

E. Xor Tree

题意:

一个数组。每个元素会和与自己异或值最小的数连一条无向边。想要最终形成的图是一颗树。 至少要删掉几个元素。

思路:

首先肯定不会形成环。

为什么呢。因为一个值,只会和一个异或起来最小的值相连。要形成环。就说明至少要有一个元素。同时连向两个元素。这显然不符合条件。环中边的数量等于点的数量。但是题目的条件中。必然至少存在一对。两两异或互为最小的。也就减少了一条边。所以不可能形成环。

既然不会形成环,还有一种不是树的情况。就是形成了森林。或者说多个连通块。比如数组中 a-b 异或起来互为最小。 c-d异或起来互为最小。这时候就必须要删点了。

具体怎么删。考虑贪心。

建一颗01字典树。那么和自己异或以来最小的数。一定是同一颗子树上的,公共前缀越长越好啊,这样高位都是0。低位才会出现1。

然后就会发现,如果,一个点的左右两颗子树。都存在超过两个叶节点。那么完了。左子树的点互相连接形成连通块。右子树的点互相连接形成连通块。而左右子树 不会连边,也就是不连通。那就不可能形成树了。

所以这时候必须抉择。其中一颗子树。最多只能有一个叶子节点。其他的得删掉,那因为要贪心的考虑。肯定是选择,叶子数量大的那一颗留下来。小的那一颗删到剩下一个点就行了。

递归处理整颗树。就完成了。

AC代码:

#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值