我退坑很久了,这篇文章不是因为刷OJ而写的总结,毕竟菜鸡老年人, 23333
之前我学网络流看的是算法书和别人的博客然后就开始套板子,而这次因为考试不得已把课本上的定理都看了一遍,瞬间对最大流算法更加清楚了。
1.定义
在学习网络流算法前要了解的一些知识。
1.对于一个有向的网络$G=(N, A, C)$,其中的$c_{i,j}$表示弧$(i,j)\in A$的容量,并设$s,t$为发点和收点,令
$$
x_{i,j}=通过弧(i,j)的流量
$$
2.对于一个满足流量限制的流量称之为可行流,其中限制条件为
(1)守恒方程(对于非收发点,流入流量等于流出流量)
$$
\sum_j x_{i,j}-\sum_j x_{j,i}=\left\{
\begin{aligned}
+v,\,\,\, i =s \\
0,\,\,\, i \neq s,t \\
-v,\,\,\, i =t
\end{aligned}
\right.
$$
3.设P是G中从s到t的无向路,若弧$(i,j)$的方向是从s到t,那么称之为前向弧,否则为后向弧。
4.如果对于G的一个无向路P,有前向弧$(i,j)$,$x_{i,j} < c_{i,j}$。有后向弧$(i,j)$,$x_{i, j}>0$则称P为增广路。
2.算法思想
以Ford-Fulkerson算法为例进行介绍
最大流算法的思想是找一条增广路,对其进行增加流量值,使其变成一个新的可行流,直到找不到增广路。
可是为什么是增广路呢?
那是因为增广路有且仅有以下两种情况,均可以增加流量
1.增广路上都是前向弧。
图中黑色数字表示边容量,红色数字表示现有流量。下图同。
对于这种情况,直接对每个边上进行流量的增加就好了。
2.增广路上有后向弧。
这种情况才是网络流中的重中之重。
对于前向弧进行流量的增加一个单位,对于后向弧进行流量的减少一个单位。
为什么要这么做呢?观察弧$(5,4)$,如果我们把这个弧上的流量退掉,那么退掉的这部分流量就可以增加到弧$(5,6)$上,保持节点5的流量守恒,因为节点5的退流,节点4流入的流量就减少一个单位,但是我们把节点4前面的前向弧都增加了一个单位,因此同样保证了节点4的守恒,同时增加了流量。
所以可以利用后向弧的这个特点对增广路进行流量的增加。
这样就得到了增广路的所有情况均可以对流量进行增加。
3.算法的理论证明
下面为网络流的两个主要定理:
1.增广路定理:一个可行流是最大流当且仅当不存在关于它从s到t的增广路。
证明:
首先求出最大流的上界
定义一个弧割$(S,T)$,其中$s\in S, t\in T$ 【弧割:去掉使得图强连通的分支严格增加的边的集合,这里指的是去掉使得图的点集合N被分成S和T两个集合】
那么割$(S,T)$的容量定义为$C(S,T)=\sum_{i\in S}\sum_{j\in T}c_{i,j}$
因此可知从s到t的流量v不会大于$C(S,T)$,即
$$
v\leq C(S,T)
$$
然后证明这个这个可行流是最大流
取S为从s可按照增广路到达的点集合,$T=N-S$,那么可以得到对于任意的$i\in S$和$j\in T$,有前向弧为满流状态,后向弧为0。(因为从i到j已经没有路可走了,只有这两个状态)
因此有
$$
v=\sum_{i\in S}\sum_{j\in T}x_{i,j}=\sum_{i\in S}\sum_{j\in T}c_{i,j}=C(S,T)
$$
由最大流的上界可以保证此时达到最大流。
2.最大流最小割定理:一个$(s,t)$流的最大值为$(s,t)$割的最小容量。
证明;
根据前面的证明可以知道最大流为C(S,T)的下确界,而在推到过程中可以取到,所以该定理成立。
然后所有的理论工作就完成了,剩下的就是对网络进行DFS或BFS直到找不到增广路为止。
原文地址:https://www.cnblogs.com/cniwoq/p/9245813.html