1 条题解
-
0
你发来的题目是 COCI 2018/2019 Contest #1 T5「Teoretičar」,和之前我给出的那道「Praktični」不是同一题。这是二分图边着色问题的一个特殊版本。我来为你写这道题的题解。
题目大意
给定一个二分图,左部 个点,右部 个点, 条边。
要对边进行着色,使得每个顶点所关联的边的颜色互不相同。
设最小可能的颜色数是 ,令 为 的最小 的整次幂,我们只需要用不超过 种颜色给出一个方案。
思路分析
1. 理论基础
这是一个经典的二分图边着色问题,由 Kőnig's line coloring theorem 可知:
对于二分图,最小边着色数等于最大度数 。
因此 (最大度数)。
题目要求:使用颜色数 ,且 是 的最小 的整次幂,即
[ K = 2^{\lceil \log_2 \Delta \rceil} ] 我们可以使用 种颜色来完成着色,而 。
2. 构造方法
我们需要构造一个 -边着色的方案。
常见构造方法:依次处理每条边,维护每个顶点可用的颜色集合,用类似贪心+调整的方法。重要观察:
颜色用 到 编号(输出时 )。
因为 是 2 的幂,我们可以利用位运算性质。
3. 算法描述
核心想法:
假设当前要加边 。
令 = 在左点 上未使用的最小颜色编号(在 中)。
令 = 在右点 上未使用的最小颜色编号。如果 ,直接涂这个颜色,完成。
否则 ,我们尝试把右点 的某个邻接边的颜色改成 ,然后递归调整。
这个过程类似增广路调整,但由于二分图的特殊结构和颜色数是 2 的幂,可以保证在有限步结束且不会冲突。具体步骤:
- 在右部点 上,我们想用颜色 ,但 已被某条边 占用。
- 那么我们把 改成颜色 (这是 上未用的颜色)。
- 然后在左部点 上,颜色 可能已被 占用,重复这个过程。
- 这形成一条交替路径: 想用 ,然后 改 ,然后 想改 ,... 直到某个右点 上 未使用,或某个左点 上 未使用,调整结束。
可以证明,因为 是 2 的幂,这条路径不会形成环,且一定在有限步内结束。
4. 维护可用颜色
每个顶点维护一个未使用颜色集合,可以用布尔数组或集合,但为了快速找最小未使用颜色,可以用位运算优化:
用一个整数mask表示可用的颜色( 最多 ,,但 是 2 的幂,最多 种颜色,所以整数位足够表示)。- 初始
mask = (1<<K)-1,表示所有颜色可用。 - 当使用颜色 ,就
mask &= ~(1<<c)。 - 当释放颜色 ,就
mask |= (1<<c)。 - 找最小可用颜色:
__builtin_ctz(mask)(gcc 内置函数,找最低位 1 的位置)。
5. 复杂度
每条边调整过程可能遍历一条交替路径,长度不超过 ,而 ,最坏 可能过大?
但实际上,由于 是 2 的幂,调整路径长度较短,且每个点的可用颜色集合的维护是 ,整体可在 或 内完成,在数据范围内可接受。更优实现:使用邻接表存每个点的边(颜色,对端点),并快速修改。
6. 算法步骤
- 读入图,计算最大度数 。
- 计算 。
- 初始化:每个左点、右点的可用颜色掩码为 。
- 按输入顺序处理每条边 :
- 找 = 左点 最小可用颜色, = 右点 最小可用颜色。
- 如果 : 涂色,更新两个点的掩码(去掉该颜色)。
- 否则: 执行调整过程(从右点 开始,交替改颜色,直到可以插入 或 )。
- 输出颜色(记得 因为题目颜色从 1 开始)。
7. 样例验证
样例 1
最大度 (点1左度2,点2左度2,右部点度最大2),
。
构造可得方案如样例输出。样例 2
最大度 (左点1度3),
(因为 是 的最小 2 的幂)。
所以输出 4 种颜色允许,方案如样例。
总结
这道题的关键点:
- 利用 Kőnig 定理知道最小颜色数 。
- 放宽到 的幂 是为了方便构造,利用位运算快速找可用颜色。
- 用类似增广路调整的方法依次加边并保持颜色不冲突。
- 由于 是 2 的幂,调整路径不会循环,总能结束。
这样就能在 时间内完成构造,满足数据范围要求。
- 1
信息
- ID
- 3839
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者