网络流入门
网络流入门
写在前面
本文是笔者第一次学习网络流写的 $\text{blog}$,可能比较简陋,但还是尽可能让所有人看懂 qwq。
本篇主要介绍网络流算法,具体题目的建模可以看这一篇。
网络流引入
- 网络流,简单来说就是在一个很多水管的地方,水流从起点流向终点,在水管有多种限制的情况下最大化总流量。
网络
一个有向图 $G=(V,E)$,满足以下两个条件则为网络。
$1.$ $\forall e=(u,v)\in E$(称为弧),都有一个称为容量的值 $w=c(u,v)$,也可记作弧 $(u,v,w)$。
$2.$ 此图内有且仅有一个起点(源点)$S$ 和终点(汇点)$T$。
流
我们记 $f(u,v)$ 表示 $u$ 到 $v$ 的流量。
对于网络中的一个路径,满足以下两个条件则为流。
$1.$ 容量限制:对于路径上的每条边,流经该边的流量不能超过其容量,即 $f(u,v)\le c(u,v)$。感性理解为水管粗细有限,只能接受一定量的水流。
$2.$ 流量守恒:除了源点 $S$ 与汇点 $T$,路径上的每个点流入流量等于流出流量,即 $\sum_vf(u,v)=\sum_xf(x,u)$。感性理解为水管不能储存水,也不能凭空变出水。
残量网络
一个网络经过流的操作就变成残量网络。
我们用 $r(u,v)$ 表示残量网络,一开始 $r(u,v)=c(u,v)$。其实就是边的剩余容量。
对于每一次流的操作,$r(u,v)-=f(u,v)$。
因为流的相对性,一个流 $f(u,v)=x$,也同时会让反向边 $f(v,u)=-x$,这一点被称为反对称性。
所以对于一次流,$f(u,v)+=x$,$f(v,u)-=x$,$r(u,v)-=x$,$r(v,u)+=x$。
增广路
在残量网络中,找到一条从 $S$ 到 $T$ 的路径,其中所有边剩余容量都不为 $0$,则称此路径为增广路。
简单来说,就是没流满,还能流,使答案增加的路径。
而当一个残量网络中不存在增广路,则此时汇点得到的流量就是网络中的最大流。
反悔操作
上面好像是很完备的定义吧……等等,为什么 $r(v,u)+=x$,剩余容量还会增加?
原因是下一次再流的时候会抵消掉这一次的流量,相当于无事发生,也就是所谓反悔操作。
理解一下,反向边的设定和反悔操作其实是为了避免直接贪心导致的错误答案。
我们先看个图,红色边表示原边,绿色边表示反向边,边上的数字表示剩余容量。
然后我们先尝试增广路径 $(1,2,3,4)$,流量为 $10$,则残量网络如下(注意反向边的剩余容量增加)。
我们再增广路径 $(1,3,4)$,流量为 $10$。
如果没有反向边,已经返回了错误答案 $20$。但现在我们发现,图竟然还能增广,路径 $(1,3,2,4)$,流量为 $10$。
唯一的区别是这一次路径上有一条反向边,流过此边表示反悔操作,得到最大流 $30$。
这样流和直接增广 $(1,2,4)$ 与 $(1,3,4)$ 答案相同,避免了顺序问题导致的答案错误。
最大流
FF 算法
每次在残余网络中利用 $\text{dfs}$ 任意找一条从源点 $s$ 到汇点 $t$ 的增广路,直至不存增广路为止。
每次 $\text{dfs}$ 的复杂度是 $O(m)$ 的,可能有数据会卡到每次只能增广 $1$。如下图。
这个图中可能会因顺序导致一直在走 $(1,2,3,4)$ 和 $(1,3,2,4)$,每次只增广 $1$。
这样算法的复杂度是 $O(m\times \max w)$ 的。
|
(此代码经格式化)
EK 算法
$\text{dfs}$ 太呆啦!我们在 $\text{FF}$ 算法的基础上使用 $\text{bfs}$ 找增广路,此时每次找的都是最短的增广路。
复杂度证明:
每次寻找增广路复杂度 $O(m)$。
我们接下来证明每条边最多成为 $O(n)$ 次路径流量上界(即是该残量网络中该路径上的容量最小值)
首先,对于 $(u,v)$ 是流量上界,有 $d_u=d_v+1$。
而增广后,$r(u,v)=0$,如果想要再次使用这条边,必须要走反向边反悔,即 $d’_u=d’_v+1$。
但因为这条路径是最短的,所以 $d’_v\ge d_v$,所以 $d’_u\ge d_v+1$,推出 $d’_u\ge d_u+2$。
因此,每次增广都会使 $S$ 到 $(u,v)$ 的最短距离至少增加 $2$。
因为最短距离上界是 $O(n)$,所以增广次数上界也是 $O(n)$。对于所有边,总增广次数上界 $O(nm)$。
所以我们得到,$\text{EK}$ 算法的复杂度上界是 $O(nm^2)$。
实际上这个上界很松,可以跑过 $10^3-10^4$。
我的证明并不严格,更加好的证明可以上 $\text{wiki}$ 查看 qwq。
给出模板题的代码实现。
|