最小割树
注意!
- 在边很多的时候用邻接矩阵,边很少时要用前向星
- 从
2
开始循环!
题目大意
给定一个无向图
朴素做法
对于每次询问,我们做一次最大流,复杂度
这时我们可以先预处理出所有点对的最大流,然后根据每个询问输出答案。
朴素预处理的复杂度
提出问题
那么我们如何快速预处理出所有点对的最大流呢?这就是这题所要考察的内容。
按照惯例,我们考虑问题要从简单入手,然后推到一般化。注意图是无向的。
那图的简化是什么?没错,是树。
那么假设现在有一颗无向树,求所有点对的最大流用 LCA+RMQ 即可解决。(例如:2857—TT 的身体)
那么对于图,我们理所当然想到要去构造一棵等价于原图的最大流树。
图
Gomory-Hutree 是一颗代表了所有源目节点对间的最小割的树。
求解出 Gomory-Hutree 就可以了解两两节点对之间的最大流(最大流最小割定理)。
举例:一个有
步骤一:创建一棵星型树,节点
步骤二:分别选编号为
步骤三:在星型树中令与
将最大流标注在星型树中
步骤四:对于每一个编号大于
最后可得到如上图右侧所示的 Gomory-Hutree。
算法步骤
- 首先任选一个点为根。设以结点
为根,标记1 已经 check,把所有的结点都连到根1 。1 - 按顺序枚举未 check 的节点
,比如以从小到大的顺序。𝑇 - 设
为此时结点𝑆 的父亲,在原图中求𝑇 -𝑆 的最大流𝑇 - 从结点
开始 DFS𝑆 - 把在
-𝑆 割中属于𝑇 侧的未 check 结点设为𝑇 结点的儿子;标记𝑇 为 check𝑇 - 重复直到所有的点都被 check。注意
-𝑆 的最大流为𝑆 0
- 设
时间复杂度
由于
所以复杂度是
预处理所有点对的最大流可以在更新树的同时一起更新,而无需最后再 LCA+RMQ。