感谢 Alex_Wei 的博客,让我受益匪浅。
回忆 Kruskal 算法的过程,按边权从小到大排序,若当前边 在当前图上还不连通,则加入该边,并查集维护这个过程。
Kruskal 重构树就是在加入 时,建立虚点 ,令点权 ,建边 和 ,并将 设为 。这样得到一棵 个点的二叉树,初始的节点都是树上的叶子,且满足大根堆的性质。
一个应用是求出 只经过边权 的边最多可以到达多少个节点。因为 ,可在重构树上倍增,找到 深度最浅的祖先 满足 ,答案为 的子树内的叶子个数。
当问题变为点权的限制后,也可以用重构树解决。一种解决方法是将 设为 ,然后用边权的方法做。
存在另一种不需要建虚点的建树方法。按点权从小到大排序,设当前考虑到点 ,遍历每条边 ,若 已被考虑过即 ,且 不连通,则建边 。这样构造显然也满足大根堆的性质,但是它是一棵多叉树。
例题
CF1797F Li Hua and Path
求出满足一类限制,满足二类限制,满足一类和二类限制的答案 ,答案即为 。
考虑加入父亲为 的点 对 的影响。 增量显然是 , 和 的增量相同,设 表示有多少条路径 满足 是路径上的最小值, 增量就是 。考虑 如何转移,因为若路径 满足 是路径最小值,则 一定也满足,再加上路径 ,即 。综上,每次增量为 。
于是只需处理初始的 和 即可。建出小根堆和大根堆的点权多叉重构树 和 。点 对 的贡献是 分别在 和 的 ,因为子树内的点都是可以满足 或 的限制到达的。 就是 在 上的深度。 也就是统计有多少 满足 在 上是 的祖先, 在 上是 的祖先,这个树状数组随便计算就好了。复杂度 。
P4768 [NOI2018] 归程
这个就是上述的经典应用。建出 Kruskal 重构树,找到第一个 满足 ,在 的子树内找 最小值即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!