《算法分析与设计》学习笔记
作业占
Lecture 1:近似最短路
内容:Dijkstra,APASP,近似距离查询。
很多内容 xtq 在 WC2024 上讲过。
最短路问题
记
使用斐波那契堆优化的 Dijkstra 的复杂度为
对于 APSP,Floyd-Warshall 的复杂度为
无向无权图 APASP
设
- stretch
近似满足 。 - surplus
近似满足 。
surplus
准备工作
独立随机以
定理
给定度数
,可以找到大小为 的点集 ,满足所有度不小于 的点大概率和 相邻。
设
设
算法流程
- 从每个
跑 BFS 求出 ,其中 , 。时间 。 - 从每个
在 上跑 Dijkstra。时间 。
算法的时间复杂度
算法分析
- 若
或 ,则 在第一步求出。 - 若
最短路径上所有点的度小于 ,则每条边在 上, 在第二步求出。 - 若存在度不小于
的点 ,则 和 相邻, 。
通过
surplus
这个算法还有可以利用的性质:最短路径要么只有
改改阈值会发生什么?
设
再分一层
对于路径上有度在
但这样还有一个问题,就是
算法流程
- 从每个
跑 BFS 求出 ,其中 , 。时间 。 - 从每个
在 上跑 BFS 求出 ,其中 , 。时间 。 - 从每个
在 上跑 Dijkstra。时间 。
通过
通过
算法分析
- 若
或 ,则 在第一步求出。 - 若
最短路径上所有点的度小于 ,则每条边在 上, 在第三步求出。 - 设
是路径上最后一个度在 和 之间的点, 且 。路径 且三部分分别属于 , 和 。
扩展
分更多层会出现更多中转点,可以做到
无向无权图 surplus
surplus
普通
大概思想是观察到
没讲怎么改进
分成
近似
算法流程
对每个
- 从
的每个点在 上跑 BFS 求出 。时间 。
设
- 用
和 更新 。
算法分析
考虑
设
- 当路径长度是偶数时,如果
不在中点,不妨设靠近 一侧,那么 。如果 在中点,那么考虑度数次大的点 以及对应的 ,根据 的定义可知路径上所有边在 上,此时 一定不在中点。 - 当路径长度是奇数时,
。当 和 分别是最中间一条边的两端时,不等式可能取等。
为什么无向无权
对于有向图,以上算法显然行不通。
对于带权图,和一个点相邻不一定距离这个点近。可以考虑乘法近似。
无向带权图 APASP
截断 Dijkstra
考虑求出距离一个点最近的
时间
stretch
类似的思想。
设
这样,从
显然复杂度为
Cohen-Zwick 在 1997 年做到了
近似最短路查询
以上讨论给出了使用
可以用
Lecture 2:斐波那契堆
内容:二叉堆、二项树、斐波那契堆。
以下所有内容考虑小根堆:每个点的权值不大于其儿子权值。
二叉堆
堆的结构是一棵完全二叉树。根是最小值,树高
如何实现?用指针维护父亲和儿子关系,或左儿子两倍右儿子两倍加一。
查询最小值
插入
将
减法
将元素的值减去
删除最小值
将根和最右侧叶子交换,向下冒泡(和较大的儿子交换)。
合并
暴力合并。
二项堆
二项树
性质:
。 深度为 。 的第 层有 个点。
定义一个 结点的阶 是其儿子个数,一棵 二项树的阶 是其根的阶。
原则:只合并同阶二项树。
二项堆
二项堆维护的过程借助了二进制分组的思想保证复杂度:一旦有两棵同阶二项树,则合并。因此,若二项堆的大小为
一个二项堆最多有
合并
模拟二进制加法。
删除最小值
找到最小值,删去。对应二项树分裂成若干二项树,与原有二项树合并。
减法
向上冒泡。
删除
减到
插入
二进制模拟加
查询最小值
斐波那契堆
斐波那契堆只有删除(最小值)的复杂度为
从空斐波那契堆开始,任何
做到
其基本想法和二项堆类似,但对结构的要求更宽松。二项堆在每次操作后立刻重构,斐波那契堆采用 懒重构 的思想,直到删除最小值之后再重构。
维护:
- 一些堆。
- 根的列表和最小值指针。
- 结点的标记:表示该结点已经失去了一个儿子。如果再失去一个,则以它为根的子树会被剪下来。
设
定义均摊时间为实际用时加上势能的变化量,则总用时不超过总均摊时间之,因为势能非负且初始为
插入
将结点插入根的列表,更新最小值指针。
时间
合并两棵树
将较大的根连到较小的根下面。
删除最小值
把根的所有子树全部融到根列表,重构使得没有根的阶相同。
时间
在只有前述操作时,
减法
如果堆性质没有被破坏,则直接减。
否则把以
如果不特殊处理,这一步会扭曲树的形态,导致
设剪下子树的次数为
分析
将
设
合并
用双向列表维护根列表。
时间
应用
最小生成树
在 Dijkstra 或 Prim 的过程中使用斐波那契堆,
最小生成树
Fredman & Tarjan [1987] 通过限制堆的大小做到了更优的复杂度:考虑结合 Boruvka 和 Prim,从某个点开始,如果堆里有
取
因此,当
目前学术界的 MST
随机算法
确定算法
最优算法(复杂度仍为 open problem) [Pettie, Ramachandran 2002]。
判定 MST
Tarjan 老爷子是真牛啊。
Lecture 3:并查集
内容:并查集的复杂度分析。
问题描述
初始
并查集是维护不交集合的数据结构,每个集合用一个代表元表示,支持:
- Makeset(x):新建包含元素
的集合。 - Find(x):查询
所在集合的代表元。 - Union(x, y):若
处于不同集合,则合并它们所在的集合,删去原有的两个集合。
以下设
链表
用链表维护,每个元素指向下一个元素和代表元。
makeset
如果不维护代表元指针,则 find
启发式合并
将较短的链表添加在较长的链表后,时间
Up-tree
每个点指向其父节点,没有父节点的点为对应集合代表元。
合并可能导致树的深度达到
按秩合并
将深度较小的树合并到深度较大的树:深度为
将大小较小的树合并到大小较大的树:每个点被合并时,其所在集合大小至少翻倍。
时间复杂度
路径压缩
查询时将路径上的每个点都指向代表元。
复杂度分析
重点是分析路径压缩按秩合并的并查集的复杂度。
设
因为 union 等价于两个 find 和一个 link,且 makeset 和 link 显然为
考虑
对于那些翻倍的点,最多发生
时间为
设
设
考虑一次 find 从
- 若
,则总赋值次数不超过 。 - 若
,则总赋值次数不超过 。 - 若
:- 若
,考虑到每个点的父亲的秩最多一次从不超过 变成大于 ,总赋值次数不超过 。 - 若
,每次操作最多一个这样的点,总赋值次数不超过 ,其中 表示涉及到阶大于 的点的 find 次数, 。
- 若
于是
取
Ackermann's function
定义
分析
对于
第二项不超过
取
记
得
不断重复上述过程,得
因此时间为
是否存在更优美的复杂度分析?Tarjan 同时证明了这个算法的时间下界
复杂度下界分析
略。
对任何并查集,有
Lecture 4:动态树
Splay
设
Splay 引理:每个 splay(x, S)
操作需要
- 每个 Zig 不超过
。 - 每个 Zig-Zig 和 Zig-Zag 不超过
。
证明的 nasty-case 是
动态最优性猜想:
LCT
对 link 的要求:
对 delete 的要求:删除树边。
每个结点有 0/1 个偏好的孩子。用 Splay 维护偏好链,每个 Splay 指向父亲。
access 打通
ETT
用 Splay 维护欧拉序。
换根:考虑
换根之后容易做 link 和 cut。
LCT 做链问题比较优秀,ETT 做子树问题比较优秀。
Lecture 5:动态连通性
完全动态连通性
加边删边查询连通性。想法:维护生成森林。
加边容易,但删树边时需要找到重新连接两部分的边。
每条边有只会增加的等级
维护
- 若
是非树边,则 在 上连通(生成森林极大)。 - 若
是树边,则 在 上也是树边。 的每棵树的大小不超过 。
可知若一条边在
加入
删除
动态子图连通性
忽略所有
每个点有开关状态,支持修改一个点的状态,以及查询两个点能否通过开着的点连通。
维护两个集合
用删边维护的方法维护
维护新图
如果
对于查询:
- 对于
里的点, 查询在哪个连通块。 - 对于大连通块的点,查询在
上表示这个大连通块的点,再查询在哪个连通块。 - 对于小连通块的点,找一个
里的点与其相邻。若不存在则孤立。 。
对于预处理:
和 都需要 的时间。- 每
次修改重构一次,所以均摊到每个修改 。
对于修改:
- 当加入或删除
的点时,更新 的每个点和这个点的连接情况。 。 - 删除小连通块的点时,重新计算相关的
。 。 - 删除大连通块的点时,按度数之和从大到小记分裂成的连通块为
。- 删掉
的边的总数为 ,所以每个修改 。 - 如果
是大连通块,则更新 需要 的时间。 减半,最多 轮。 。 - 如果
从大连通块变成小连通块,则更新 。因为只会变一次,所以 。
- 删掉
Lecture 6:最大流
FF
每次找一个增广路。若所有容量是
整性定理:若网络所有容量都是整数,则存在所有边的流量都是整数的最大流。
EK
选增广路的时候不要随便选。选最大瓶颈路,足够大容量的路,或者最短路。
Capacity Scaling
设
需要强多项式算法。
最短路
指边数最少的路径。
考虑最短路分层图,每次删去至少一条边,反边不会出现在分层图上。最多增广
Dinic
不要每次都在分层图上重新找,一次找完即可。
用 LCT 维护分层图的生成树,
单位容量最大流
任意图
无向图
在残量网络上,只有有流量的边有方向。在单位容量无向图上,任何无环流可以被分解为路径。
如果残量网络的最大流为
因为最大流不超过
Lecture 7:最小割和 k 连通性
全局最小割
有平凡的
Karger' Algorithm
随机选一条边收缩,只剩两个点时得到割,但不一定是最小割
因为每个点的度数不小于
于是复杂度
考虑在还剩
正确率
即
设
不能用在 s-t 最小割,因为度数下界没有保证。
k 连通性
最简单的一集。
k 边连通:删去少于
k 点连通:删去少于
若 k 点连通,则 k 边连通。
双连通分量的判定:Tarjan。
耳分解不在考纲内,略。
Lecture 8:原始对偶松弛算法
集合覆盖
一个元素的频率为它所在的集合数量,
集合覆盖写成整数线性规划 IP:对每个
松弛成线性规划 LP:
LP 的最优解显然不劣于 IP 的最优解。
线性规划
最小化
LP 算法的复杂度,其中
- Simplex:指数,但很快。
- Ellipsoid:
。 - Interior Point:
。
Open Problem:是否存在强多项式的算法。
对偶:最大化
根据
即
而
所以
LP-duality Theorem
若原始线性规划问题的最优解空间有限,则其对偶问题的最优解空间有限。若
证明略。
Complementary Slackness Conditions(互补松弛条件)
根据
对集合覆盖,
这是纯组合的算法,无需求解 LP。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!