Dotcpp  >  编程教程  >  图论  >  网络流的基本概念

网络流的基本概念

点击打开在线编译器,边学边练

什么是网络流?首先大家要知道网络流在图论中是尤为重要的。在这里,给大家介绍网络流中的一些基本知识。


一、网络流的概念和定义整理

在图论中,网络流(英语:Network flow)是指在一个每条边都有容量(Capacity)的有向图分配流,使一条边的流量不会超过它的容量。

1. 流网络

流网络是一种特殊的有向图。

一个网络可以表示成一个点集和边集的集合,即:G=(V,E)。

V表示点,流网络有两个特殊点,分别是源点和汇点。

E表示边,流网络中每条边都有一个权重c,被称之为容量(Capacity)。

(1)源点 & 汇点

可以把流网络类比成一个由一条条河流组成的网络。

源点(Source)有无穷的的流量可以向外流出,汇点(Sink)有无穷的容量容纳流量。

(2)净流

通过流网络的一条边的流量(净流)记为f(u,v)。


可行流

可行流常用 f 表示,在流网络中满足以下条件的网络流称为可行流。

(1)容量限制(Capacity Constraints):

容量限制

(2)流守恒(Flow Conservation):除了源点和汇点,所有点流出流量之和=流入流量之和

反之,如果只满足容量限制不满足流守恒则称之为伪流。


可行流的流量

每秒从源点流出的净流量或者每秒从汇点流入的净流量就是该可行流的流量:

可行流的流量

式子也可以用汇点来表示。式子后半部分表示减去流回源点的流量。


最大流

最大流即为最大可行流,最大流的流量是所有可行流中最大的。


2. 残留网络 Residual Network

 残留网络

一个显示了流及容量的流网络及对应的残留网络

残留网络是由流网络G和可行流 f 决定的一个流网络,记为残留网络,它显示可用的容量的多少。

残留网络的点等于流网络G的点:

残留网络

残留网络的边等于原本的边和反向边之和

每条边的容量可以表示为:

每条边的容量

分别表示剩余可用流量和反向流量(可以退回的流量)。


残留网络也是一个流网络,因此也有可行流的概念

定理:原网络的可行流 f 加上 残留网络的一个可行流 f′ 也是原网络G的一个可行流 :|f+f′|=|f|+|f′|


3. 增广路径 Augmenting Path

增广路是一条路径 (u1,u2,⋯,uk),而 u1=s 、uk=t及 cf(ui,ui+1)>0,这表示沿这条路径传送更多流是可能的。

定理:一个可行流当且仅当剩余网络 Gf 没有增广路时处于最大流。


4. 割 Cut

割将一个流网络G分为两个图S和T,记为[S,T],满足:S∪T=G

且:S∩T=∅

源点满足 s∈S,汇点满足 t∈T


(1)割的容量

所有从S指向T的有向边的容量之和为割的容量:

割的容量

从T指向S的边则不被计算。


(2)割的流量

类似割的容量,割的流量被定义为:

割的流量

可以注意到,容量流量的定义不对称,容量只考虑正向边,流量考虑双向边


(3)最小割

容量最小的割即为最小割


(4)割的性质

对于任意割,割的容量大于等于割的流量∀[S,T] f(S,T)≤c(S,T)

一个割只有一个容量,但可能有很多个流量(可行流),割的容量大于所有这个割的流量。

观察一下容量和流量的表达式,这条性质是很容易理解的。

对于任意一个可行流,和任意一个割,可行流的流量等于割的流量|f|=f(S,T)

这个可以形象的理解,从源点流出的净流量一定全部流向了汇点,而割将源点和汇点分为了两部分,所以这些净流量一定流经了割。

对于任意可行流,任意割,可行的流的流量一定小于割的容量

第一条性质再结合第二条性质,可以得到:|f|=f(S,T)≤c(S,T)

也就是:|f|≤c(S,T)

由于 f 是任意的流,割是任意的割,因此最大流的流量一定小于等于最小割的容量。后面会证明,如果是这种情况的话,这里其实是取等号的。


最大流最小割定理:网络流的基石,核心概念

首先列出三个命题:

对于一个流网络G

(1)f 是最大流

(2)Gf中不存在增广路

(3)∃[S,T],|f|=c(S,T)∃[S,T],|f|=c(S,T)

最大流最小割定理证明了这三个命题是等价的。

1⟹2

首先证明1式可以推得2式,使用反证法

假定 f 是G的最大流,且残留网络 G存在增广路,那么 Gf 中必定存在一个流量大于0的可行流 f′。

由定理 |f+f′|=|f|+|f′| ,可得 |f+f′|>f,这与 f 是最大流相矛盾,因此 G中不存在增广路,证毕。

2⟹3

尝试构造一个割,在残留网络 Gf 中从源点s沿着正权路径遍历,能到达的所有点组成 S ,其他点组成 T 。这样就构造了一个合法的割。注意,这里的构造出的割是针对原图的割,而不是残留网络。

在 S 中任取一点 x ,在 T 中任取一点 y ,可以证明 f(x,y)=c(x,y),且 f(y,x)=0:

(1)假定 f(x,y)<c(x,y),那么在残留网络中就存在一条c(x,y)−f(x,y)>0的边,按照构造割时候的方法,y 点应该在 S 中,这与假设矛盾,所以 f(x,y)=c(x,y)。

(2)假定 f(y,x)≠0,由于残留网络会建反向边,所以在残留网络中,必定存在 f′(x,y)>0,同样按照构造割的方法,y 点应该在 S 中,这与假设矛盾,所以 f(y,x)=0。

前面提到,对于任意一个可行流,和任意一个割,可行流的流量等于割的流量:|f|=f(S,T)

所以:

割的流量

又因为在构造的割中,f(x,y)=c(x,y),f(y,x)=0,所以:

构造的割

3⟹1

这里要证明的是3式中的 f 就是最大流。

不妨记最大流为F

首先|F|≥|f|,又因为 |f|=c(S,T)≥|F|,所以 |F|=|f|,证毕。

这个式子还可以继续推导,记最小割为最小割

最小割

又因为最小割的容量大于等于最大流的流量

最大流的流量

所以最小割的容量等于最大流的流量

最大流的流量

和起来就是:

1⟹2⟹3⟹1

所以这三个命题是等价的,这就是最大流最小割定理


二、网络流的常见问题

网络流问题中常见的有以下三种:最大流,最小割,费用流。

(1)最大流

我们有一张图,要求从源点流向汇点的最大流量(可以有很多条路到达汇点),就是我们的最大流问题。

(2)最小费用最大流

最小费用最大流问题是这样的:每条边都有一个费用,代表单位流量流过这条边的开销。我们要在求出最大流的同时,要求花费的费用最小。

(3)最小割

割其实就是删边的意思,当然最小割就是割掉  条边来让  跟  不互通。我们要求  条边加起来的流量总和最小。这就是最小割问题。


知识点标签:图论


本文固定URL:https://www.dotcpp.com/course/1070

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

算法竞赛教程
第一章 算法基础
第二章 搜索算法
第三章 排序算法
第四章 字符串相关
第五章 数学相关
第六章 动态规划
第七章 数据结构
第八章 图论
第九章 计算几何
第十章 其他算法
Dotcpp在线编译      (登录可减少运行等待时间)