1 条题解
-
0
问题抽象
我们有一个连通无向图, 个节点, 条边,每条边 有宽度 。
对于每个查询 ,我们需要选择一些边构成生成树,使得整张图连通,并且最小化总代价:
其中我们可以任意调整边的宽度(每调整 花费 ),但宽度不能低于 。
关键观察
1. 问题转化
实际上,我们不需要真的"调整所有边的宽度",而是选择一组边构成生成树,使得这些边宽度与 的绝对差之和最小。
因为对于不在生成树中的边,我们可以不管它们(不花费代价),只需要保证生成树中的边连通全图即可。
2. 按边权排序
将边按宽度 排序。对于固定的 ,考虑每条边的代价函数 。
这是一个分段线性函数:当 时,代价为 ;当 时,代价为 。
3. 生成树的结构
对于固定的 ,我们想要选择生成树使得 最小。
这等价于:我们偏好选择宽度接近 的边。
实际上,最优生成树可以通过以下方式获得:
- 将边按 排序
- 用 Kruskal 算法选择前 条边(按这个排序)
但直接对每个 做一次 Kruskal 是 ,不可行。
核心解法
1. 区间划分
注意到当 变化时,边的相对顺序只在某些关键点发生变化。这些关键点就是所有 (其中 )。
实际上,我们只需要考虑所有 以及它们的中点,因为 的排序只在 跨越这些点时改变。
2. 双序列维护
将边按 排序得到序列 。
对于给定的 ,代价函数 在 时是递减的(),在 时是递增的(),其中 是满足 的最大下标。
因此,按 排序等价于:
- 将 按降序排列(因为 随 增大而减小)
- 将 按升序排列
- 然后归并这两个序列
3. 生成树选择的单调性
关键结论:存在一个下标 ,使得最优生成树由:
- 最小的 条边(按原 排序)中的某些边
- 和最大的 条边中的某些边组成 其中 。
更精确地,最优生成树会选择最接近 的 条边(按 排序)。
4. 预处理所有关键区间
由于 ,但 可能很大, 非常大,我们需要高效处理。
解法思路:
- 将数轴按所有 和 分成 个区间
- 在每个区间内,最优生成树的边集不变(按 的排序不变)
- 对每个区间,计算生成树代价关于 的线性函数
- 对于查询 ,找到所在区间,用对应的线性函数计算答案
由于 , 太大,需要优化。实际上,只需要考虑 个关键点,因为生成树最多 条边。
算法框架
- 排序边:将边按 排序
- 生成关键点:考虑所有 以及它们的中点,但只保留可能改变生成树组成的点
- 区间处理:对每个区间 ,确定最优生成树的边集,并计算代价函数
- 查询处理:对每个 ,二分找到所在区间,用对应的线性函数计算答案
复杂度优化
- 关键点数量:
- 每个区间用 Kruskal 求生成树:
- 总预处理: 仍然太大
实际高效做法:
- 利用最优生成树在 变化时的单调性
- 使用双指针维护当前最优生成树
- 预处理所有"边交换"事件,当 变化时只需 更新生成树
总结
这道题的核心是:
- 问题转化:将重构问题转化为生成树选择问题
- 代价函数分析: 是分段线性函数
- 区间划分:最优生成树在 的某些区间内保持不变
- 高效查询:预处理线性函数,支持快速查询
这是一道结合了生成树理论、参数化优化和分段函数分析的高难度题目,需要深入理解图论性质和函数性质才能设计出高效算法。
- 1
信息
- ID
- 4273
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 6
- 已通过
- 1
- 上传者