网络流学习笔记#1:最大流和最小割

-3.前言

两年以前,那时连基础算法都不甚熟悉,却因为看到 Leasier 会这么多高深和深奥的算法而嫉妒,下定了决心,要学一些“看起来很高深的算法”,可是呢,一方面自己实力不足,另一方面是自己的懒惰,最终呢,也就仅仅是复制了一篇题解,过了个模板而已,至于这个“网络流”究竟是什么,还是一问三不知。

现在,终于有机会重新面对这个算法了。

-2.一些约定

( u , v ) (u,v) (u,v) 表示一条从 u u u v v v 的有向边。

s s s 表示源点, t t t 表示汇点。

如无特殊说明,我们所讲的图都是有向无环图,有且仅有一个源点和汇点。

除非有特殊强调,容量表示此条边剩余的容量(残量),原容量表示原始容量。

-1.一些定义

流网络指符合上述约定的一个有向无环图

f ( u , v ) f(u,v) f(u,v) 表示 ( u , v ) (u,v) (u,v)实际流量

c ( u , v ) c(u,v) c(u,v) 表示 ( u , v ) (u,v) (u,v)原容量

那么显然有 f ( u , v ) ≤ c ( u , v ) f(u,v) \le c(u,v) f(u,v)c(u,v)

定义一个点 u u u 流入量指所有出边为 u u u 的边流量之和。流出量反之亦然。

定义残量 d ( u , v ) = c ( u , v ) − f ( u , v ) d(u,v)=c(u,v)-f(u,v) d(u,v)=c(u,v)f(u,v)

定义的意思为 s s s t t t 的一条路径(参见图论定义)。

定义增广路是指一条路,这条路上的任意容量都为正数。

0.一些性质和常识

对于每一条边 ( u , v ) (u,v) (u,v) ,我们称其为可行流当且仅当:

  • f ( u , v ) ≤ c ( u , v ) f(u,v) \le c(u,v) f(u,v)c(u,v)
  • 流量守恒,即是对于 u , v u,v u,v 都有其流入量等于其流出量
  • f ( u , v ) = − f ( u , v ) f(u,v)=-f(u,v) f(u,v)=f(u,v)(斜对称性)

虽然一个流网络是一个有向无环图,但事实上,我们在解决这样的问题时,会对于每一条 ( u , v ) (u,v) (u,v) 都建一条反向边 ( v , u ) (v,u) (v,u),使得:

c ( v , u ) = 0 c(v,u)=0 c(v,u)=0

f ( v , u ) = − f ( u , v ) f(v,u)=-f(u,v) f(v,u)=f(u,v)

理性理解:

由于斜对称性,显然。

感性理解:

网络流是唯二可以反悔的算法

其实也就是相当于把流退回来。

那么显然有:

d ( v , u ) = c ( v , u ) − f ( v , u ) d(v,u)=c(v,u)-f(v,u) d(v,u)=c(v,u)f(v,u)

d ( v , u ) = 0 − ( − f ( u , v ) ) d(v,u)=0-(-f(u,v)) d(v,u)=0(f(u,v))

d ( v , u ) = f ( u , v ) d(v,u)=f(u,v) d(v,u)=f(u,v)

这是个很重要的结论。

1.最大流问题

定义

求在一个流网络中,初始时 s s s 有无限的流量,在满足约束的情况下,求最多有多少流量流入 t t t

如何去解决?

我们前面那堆定义显然不是写来玩的,思考一下,增广路是什么?是不是一条可以流水的路?也就是这东西是答案的一部分,其对答案贡献为(设该增广路上有 k k k 个点 e 1 e_1 e1 e k e_k ek):

∑ i = 1 k − 1 min ⁡ ( d ( e i , e i + 1 ) ) \sum\limits_{i=1}^{k-1} \min (d(e_i,e_{i+1})) i=1k1min(d(ei,ei+1))

那么显然可以通过 DFS/BFS 来求解,复杂度 O ( V E 2 ) O(VE^2) O(VE2)

真的是最优做法吗?

显然会有一些更优玄学的做法,先介绍两种: ISAPDinic

按照紫书上刘汝佳老师的话来讲,选手只需要了解 EK 的原理(就是 BFS ),考试时使用 ISAP/Dinic 就好了,把它们当做像 STL 一样的黑盒函数来用,所以这部分咕掉了。

最小割定理

相关定义

对于一个流网络有一源点 s s s,一汇点 t t t,规定两个集合 S , T S,T S,T,其中 s ∈ S , t ∈ T s \in S,t \in T sS,tT,把所有节点都划分到两个集合中的一个,这就是网络流中的割,又叫 s − t s-t st 割。

定义 C ( S , T ) = ∑ c ( u , v ) ( u ∈ S , v ∈ T ) C(S,T)=\sum c(u,v)(u \in S,v \in T) C(S,T)=c(u,v)(uS,vT)

定义 F ( u , v ) F(u,v) F(u,v) u u u v v v 的一个可行流。

最小割定理

C ( S , T ) min ⁡ = F ( s , t ) max ⁡ C(S,T)_{\min}=F(s,t)_{\max} C(S,T)min=F(s,t)max

伪证明:

C ( S , T ) = ∑ c ( u , v ) ( u ∈ S , v ∈ T ) ≤ F ( s , t ) max ⁡ C(S,T)=\sum c(u,v)(u \in S,v \in T)\le F(s,t)_{\max} C(S,T)=c(u,v)(uS,vT)F(s,t)max

换个方面,感性理解:

“割”的另一层含义是把“割”的边残量为 0 0 0,所以一个 s − t s-t st 割必然会使得 F ( s , t ) max ⁡ = 0 F(s,t)_{\max}=0 F(s,t)max=0 ,并且所有流量都在 S S S 集合中,当割消失,流量流过,流到 t t t,于是也可以得到
C ( S , T ) min ⁡ = F ( s , t ) max ⁡ C(S,T)_{\min}=F(s,t)_{\max} C(S,T)min=F(s,t)max

天才一秒记住最小割的定理:最小割=最大流。

关于最小割的一些闲话

怎么看最小割是否唯一

首先跑一次最大流,

根据最小割定理,可有推论:最小割中对于任意 ( u , v ) ( u ∈ S , v ∈ T ) (u,v)(u \in S,v \in T) (u,v)(uS,vT) 其残量 d ( u , v ) = 0 d(u,v)=0 d(u,v)=0

那么我们根据上面对“割”的说明可得这些边相当于被删了。

所以做两次 dfs,得到 s s s 所扩展得到的点数量 k 1 k_1 k1 t t t 所扩展得到的点数量 k 2 k_2 k2,若 k 1 + k 2 = n k_1+k2=n k1+k2=n,则最小割唯一,反之则不是唯一的。为什么?因为这代表有的点被夹在 ( u , v ) ( u ∈ S , v ∈ T ) (u,v)(u \in S,v \in T) (u,v)(uS,vT) 之间了。

最小割送我退役,r n m,不写了!

暂时不会更新了。

おすすめ

転載: blog.csdn.net/cryozwq/article/details/119329481