最大流最小割经典模型

一、最大流

1、二分图匹配

(1)只统计边数的二分图最大匹配

显然是可以用匈牙利算法的,但是因为匈牙利算法本质可以看做EK,最大流EK还是挺慢的,所以可以用dinic跑
从源点向左部的每个点连上一条容量为1的边,从右部每个点也向汇点连上一条容量为1的边,中间的边保持不变并设置容量为1。
证明显然,每个点只会选一次每条边也最多选一次。

(2)每个点可以用多次的二分图最大匹配

相似的,但是将源点和汇点连的边改成该边另一个点能用的最大次数,证明类似。

tips:没有奇环的图是必然二分图。

2、最小路径覆盖

求最小的顶点不相交的路径条数使得所有点被覆盖。

首先把每个点拆成入点和出点,按照原图连边,容量为1,并且从源点向每个入点连一条容量为1的边,从每个出点向汇点连一条容量为1的边,答案就是原图总点数减最大流。

证明:可以发现这个答案的实质就是点数减二分图最大匹配。很容易发现每条路径上点数都会比边数多一,那么我们用点数减去边数就是路径数量,减去最大匹配就是最小路径数量。

3、拆点

算小技巧吧,有两种情况:
1、如果题目里面对某个点的使用次数有限制,但是相邻的边不能很好地约束点的限制,那么可以把这个点拆成入点和出点,在入点和出点之间连容量为次数的边。
2、有亿些这条边的限制与上条边的限制题目可以强行通过拆点变成二分图,这种题一般从源点向入点连边,出点向汇点连边,中间按题目连。

4、上下界问题(虽然题目不多,但是最烦了)

(1) 无源汇上下界可行流

你会发现,一个很简单的想法,那就是把容量直接设成上界减下界,但如果这样如果直接最大流的话,流量是不守恒的,会出大问题,那为了平衡流量,我们可以把每个下界减在上一个点上,同时加在下一个点上,你会发现这样总流量是不变的,但是转移的时候就相当于是补上来了下界,我们只需要最后看一下每个点经过这些加减操作以后总值是多少,如果是正的就从超级源点向这个点连一条容量为总值的边,如果是负的就从这个点向超级汇点连一条容量为总值相反数的边,然后如果从超级源点连出来的那些边都满流了就说明你的流量守恒了,所以就有可行流,否则就没有。

(2) 有源汇上下界最大流

首先将它转化为无源汇的,从原来的汇点像原来的源点连一条容量为正无穷的边来使得流量守恒,然后按照无源汇的可以跑出来一个可行流。然后就是感性理解了:你建的从原来汇点像原来源点连的那条边的流量显然就是平衡的整个网络的流量,所以这个流量就是这个可行流的流量,记为f。你会发现原网络里会有一些没有榨干的流存在,那你就把从原来汇点向原来源点的的边删掉再跑一边从原来源点向原来汇点最大流,然后把答案加上f就是最终的最大流答案了(但是这个证明似乎是不严谨的,因为源点汇点改变了,严谨证明还要抵消啥乱七八糟的,可以参考OI wiki)。

(3) 有源汇上下界最小流

前面可行流的步骤显然是与有源汇上下界最大流一致的,然后跑一边从原来汇点像原来源点的最大流,用f减掉这个最大流就是答案(证明显然)。

5、多源汇

从超级源点向每个源点连一条容量为 \(+\infty\) 的边,从每个汇点向超级汇点连一条容量为 \(+\infty\) 的边,中间该怎么建怎么建。

6、关建边(虽然我也不知道为啥,但是好像的确就是这个建)

关建边:扩大一条边容量以后整个网络最大流都会变大。

一条边是关建边一定得满足两个条件:
(1)流量满了,因为如果没满的话那扩大也没用;
(2)它所在的某条从源点到汇点路径上正好是它卡住了最大流。
第一个很容易判断,残量网络是0就说明满了。第二个就说明它的两个端点可以分别从源点和汇点沿残量网络中的非零边搜到,那做两遍dfs分别标记源点和汇点分别可以搜到的点然后判断就行了。

7、退流

删掉一条 \(u\)\(v\) 的边可以先从源点到 \(u\) 跑一边最大流,从汇点到 \(v\) 跑一边最大流,减去后将边 \((u,v)\) 的容量以及残量网络容量都设为0就做完了。

证明:就是相当于把原来网络里的源点到 \(u\) 和汇点到 \(v\) 的流量利用流网络的反悔机制给它倒回去了。

8、最大流结合简单线性DP(难的不会)

一般是正常跑DP后按照转移方式从上一步向这一步连边,然后按题目要求来就行了。

9、最大流判定最小(大)答案

一般来说可以二分解决,但如果只是每次加上一个或者几个点可以直接枚举跑最大流,因为残量网络是非常优秀的(确信)。

二、最小割

1、最小割输出方案

从源点沿着残量网络容量非0的边dfs,能搜到的在源点集合里,不能搜到的在汇点集合里,两个集合中间的边为割。

2、平面图最小割/最大流转最短路

平面图最小割/最大流可以转化为对偶图的最短路。

证明:显然对偶图的每一条边就可以对应原平面图的每一条割边,那么最短路就是最小割。

3、最大权闭合子图

闭合子图:子图里每个点都没有指向子图外点的边。

我们从源点向点权为正的点连一条容量为点权的边,从点权为负的点向汇点连一条容量为点权相反数的边(点权为零因为没有任何贡献放在哪里都没有影响,下面的零同理不考虑),内部边保留且容量为 \(+\infty\),答案就是正点权和减去该图最小割。

证明:首先证明最小割肯定不包含容量为 \(+\infty\) 的边(我们称之为简单割),这个是很显然的,因为最小割等于最大流,而该图是存在关建边的,也就是流量不可能为 \(+\infty\),所以最小割也一定不可能含有容量为 \(+\infty\) 的边。我们先将所有点权为正的点都与源点放在同一个集合 \(s\) 中,点权为负的点都与汇点放在同一个集合 \(t\) 中。
那么我们现在为了选出一个闭合子图,有两种选择:
(1) 放弃一个正权点,即把一个正权点丢进 \(t\) 中,那么这个点点权为长度的边就被割了;
(2) 选上一个负权点,同理。那么我们得到的两个集合一定没有指向外面的边(因为简单割肯定没有长度为 \(+\infty\) 的边)。
所以答案就等于正点权和减最小割。

输出方案:显然就是源点沿着残量网络非0边可以dfs到的点。

4、最小权覆盖集

覆盖集:一个点集,使得无向图中每条边的两个顶点至少有一个点在该点集中。

任意图的最小权覆盖集是一个NPC问题,我们在这里考虑二分图的最小权覆盖集。考虑从源点向左部每个点连一条容量为点权的边,右部每一个点向汇点连一条容量为点权的边,中间的边保留不变,容量为 \(+\infty\),答案就是该图最小割。

证明:同最大权闭合子图,可以证明最小割必然是简单割,也就是说我们只会选到左边或者右边的边,并且每条中间的边会且仅会对应一条左边或者右边的边,也就是左边或者右边的点权,所以最小权覆盖集就等于最小割。

tips:以上是点权全正的情况,有负权可以先把负权点都选上,删掉这些点连接的边,然后再跑以上算法。

输出方案:源点沿着残量网络非0边可以dfs一边,统计左端点访问过,右端点未访问过的边,答案就是这些边中非源汇的点。

5、最大权独立集

独立集:一个点集,使得任意两个点没有边直接相连。

答案为总点权减最小权覆盖集(即最小权覆盖集同样建图方法下的最小割)。

证明:即证明覆盖集的补集一定是独立集。我们考虑反证法,如果覆盖集的补集不是独立集,那么补集里一定有边连接两个点,而这两个点又都没有被选在覆盖集里,与覆盖集定义矛盾,所以覆盖集补集一定是独立集。同样的,如果独立集补集不是覆盖集,那么一定会有至少一条边没有被其补集覆盖,那么它只能两个端点都在独立集内,与独立集定义矛盾。所以独立集与覆盖集互为补集且一一对应,得证。

tips:以上是点权全正的情况,有负权同最小权覆盖集。

输出方案:最小权覆盖集的补集。

6、最大团

团:完全子图(子图里任意两个点都有边直接相连)。

很容易发现,最大团就是补图的最大独立集。

7、最小割树

用途:你有一个 \(n\) 个点的图,想求出任意两个点之间的最小割,但是直接求太慢了,这时候你就要运用到最小割树。

建树:首先任选两个点,跑一边最小割,在新图的两个点之间连一条容量为最小割的边,然后dfs分别被割在两个集合里的点,分治重复处理两边,直到最后每个点都只属于一个集合,会发现这样形成的一定是 \((n-1)\) 条边的连通图,也就是一棵树,这棵树就是最小割树。

运用:很容易感性理解发现,新树两个点之间的最小割(就是两个点之间路径上的边的容量的最小值)就是原图最小割,那我们就相当于成功与处理出了所有点之间的最小割,而且复杂度带log,很快。

posted @ 2022-03-20 21:31  Foraino0267  阅读(287)  评论(0编辑  收藏  举报