1 条题解
-
0
问题概述
Farmer John 的农场由 个牧场和 条双向道路(长度均为 )构成,形成一棵树。
为了应对某条原有道路被阻断的情况,他修建了 条额外的双向道路,每条道路有一个正整数长度(最多 )。任务:
对于原有的 条道路中的每一条,求出如果该道路被阻断,能用来重新连接农场的最短额外道路的长度。如果没有这样的额外道路,输出 。
关键转化
将原树称为 树边,额外道路称为 非树边。
- 删除一条树边 会把树分成两个连通块 和 。
- 一条非树边 能替代 ,当且仅当 和 分别属于 和 。
- 换句话说,这条非树边 跨过 了树边 。
因此:
一条非树边 可以更新 树上 到 路径上的所有树边 的候选答案(取最小值)。
问题重构
我们初始时设每条树边的答案为 。
对于每条非树边 ,我们将 到 的路径上的所有树边的答案更新为 。
最后,每条树边的答案就是能覆盖它的非树边中的最小权值;如果仍是 ,输出 。
算法选择
我们需要高效地实现:
操作:对树上一条路径的所有边进行取最小值操作。
查询:最后询问每条边的最终值。这是一个典型的 树上路径更新,最后单点查询 问题。
树链剖分(HLD)思路
-
边权转点权
将连接 (父)和 (子)的树边的权值信息记录在节点 上。
这样,一条路径上的边权,对应路径上除 LCA 外的所有点。 -
路径更新
对于非树边 :- 找到 和 的 LCA。
- 分别更新 和 路径上的点(对应的边)的答案,与 取最小值。
- 使用树链剖分将路径分解为 条重链区间。
- 对每个区间,在线段树上进行区间取最小值操作。
-
线段树设计
- 维护区间最小值(实际是“历史最小值”)。
- 支持区间取 min(lazy 标记也是取 min)。
- 最后对每个叶子节点(对应一条边)查询最终值。
复杂度分析
- 树链剖分预处理:
- 每条非树边路径更新:(树链剖分 条区间,线段树每区间 )
- 总复杂度:
对于 是可行的。
总结步骤
- 读入树结构,建立邻接表,并记录每条树边对应的下方节点(用于边权转点权)。
- 进行树链剖分预处理(dfs1 求重儿子,dfs2 剖分链)。
- 建立线段树,初始值设为 。
- 对每条非树边 :
- 使用 HLD 将路径 拆成区间,对每个区间在线段树上执行区间取 min。
- 最后对每条树边,查询其对应节点的线段树值,若为 则输出 ,否则输出该值。
要点回顾
- 核心是将“每条树边的最小可替代非树边”转化为“覆盖该边的所有非树边的最小权值”。
- 利用树链剖分 + 线段树实现高效的路径取 min 操作。
- 注意边权转点权的技巧,避免将 LCA 对应的边错误更新。
- 1
信息
- ID
- 3451
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者