左偏树
左偏树是一种二叉的可并堆,故名思意,左偏树左边的节点多于右边节点
实现
对于堆中的每一个节点,维护一个 值,定义为其往子树走最少多少步走到空节点
我们希望维护出来的堆一直往右走就能最快走到空
左偏树最核心的操作是“合并”
考虑合并两个大小分别为 的堆
取出一个更优的点,不妨是 ,将 的右儿子和 递归合并
由于合并时一直在往右走,复杂度
插入操作可视为堆与一个单独节点合并,删除堆顶可视为将堆顶左右儿子合并
值得一提的是,左偏树支持打懒标记(全体加/乘)
可持久化
左偏树支持可持久化,类似线段树合并,合并过程不断新建节点即可
若最初总共有 个节点,考虑合并两个大小分别为 的左偏树
其遍历节点数至多为 ,最多合并 次,时空复杂度
应用
k短路
求s到t的第k短路
考虑先跑出反图上t点的最短路树 ,复杂度
考虑一条s到t的路径边集 ,记去除 上的边后的边集为
中相邻的两条边 一定满足 的起点在 终点到 的链上
显然,不同的 对应了不同的 ,我们考虑维护 即可
对于已有的一个 ,我们通过增加新边/替换最后一条边得到权值略大的集合
增加新边相当于我们要找到最小的一条以 中最后一条边的终点到 的链上的一个点为起点的非树边
替换边相当于我们要找到次小的一条以 中倒数第二条边的终点到 的链上的一个点为起点的非树边
我们考虑维护堆 ,储存点 到 的链上的点为起点的非树边
显然我们不能暴力维护它,复杂度将达到
发现 和 有大量重合,我们维护一个可持久化堆即可,复杂度
显然,上面提到的操作当我们维护出 就已经迎刃而解了
总复杂度
通过斐波那契堆优化最短路+维护堆套堆可以做到