今天终于讲了久仰其大名的网络流。
网络流基础概念:
网络流是一个有向图.
容量:每条边都有一个容量(水管的最大水流容量)
源点:出发点(水厂)。
汇点:结束点(废水站)。
流:一个合法解称作一个流,也就是一条可以从源点到汇点的一条合法路径。
流量:每条边各自被经过的次数称作其流量,最终收集的总数为整个流的流量。
三个性质:
1.容量限制:流量小于等于容量,即f(u,v)<=c(u,v)
2.流量守恒:除了源点和汇点,每个点的总流入量等于总流出量【即无法存储量】
3.斜对称性:f(u,v)= - f(u,v)
最大流:从源点能最多发出多少流量到汇点且不会超过每条边的容量
三种网络:
1.容量网络:就是容量组成的网络。
2.流量网络:实际流量组成的网络。
3.残留网络:每条边的容量减去流量得出的网络,如果是0,则视为断开。
另外,残量网络中还包含原图中所有边的反向边,容量等同于正向边在流量网络中当前流量,用于“反悔”时将流送回起点。
割
一个对于点集V的划分,将V划分为两个集合S与T,其中源点s在S中,汇点 t在T中。
对于一个流f而言:
割(S,T)间的网络流量定义为: ∑ u ⊆ S ∑ v ⊆ T \sum_{u⊆S}\sum_{v⊆T} ∑u⊆S∑v⊆T f ( u , v ) f(u,v) f(u,v)- ∑ u ⊆ S ∑ v ⊆ T \sum_{u⊆S}\sum_{v⊆T} ∑u⊆S∑v⊆T f ( v , u ) f(v,u) f(v,u)
割(S,T)的容量定义为 ∑ u ⊆ S ∑ v ⊆ T \sum_{u⊆S}\sum_{v⊆T} ∑u⊆S∑v⊆T c ( u , v ) c(u,v) c(u,v)
最小割为割的容量最小的那个。
增广路
在残量网络中s到t的一条简单路径【容量为0视作断开】
结论:
一.增广后的网络的流量等于残量网络中流量加上流量网络中流量。
二.增广后流量网络中流量增加
三.对于任意流f,任意割之间的网络流量不变。
四. 任意流的流量不超过任意割的容量。
定理:最大流最小割定理
对于一个网络G,下面三个命题总是等价
1.流f是G的最大流。
2.当前流f 的残量网络G_f上不存在增广路。
3.存在某个割使得|f| = c(S, T)成立。由引理四可知,满足条件的割必定是最小割。
最大流算法:
一.增广路算法(FF算法):
1.在图上找到一条增广路
2.去增广路上的残量最小值v。(也就是流过的路径中流量最小的那一个)
3.将答案加上v。
4,.将增广路上所有边的残量减去v,反向边的残量加上v。
重复上边4个步骤直到找不到增广路为止。
二.EK算法
该算法是在FF算法基础上的改进。
考虑每次都选择最短的增广路进行增广。
【增广路长度定义为源点到汇点经过的边数】
三.Dinic算法
对于EK算法有一个显然的优化:
EK算法是一遍bfs中找到一条增广路。
而dinic算法是一遍bfs后构建出一个可行网络,在可行网络中dfs多条增广路进行增广。
可行边:在残量网络中,若两个端点间的最短路恰好差1,就称之为可行边
可行网络:由可行边组成的网络
然后发现网络流的模板其实很容易,但主要关键是对一个问题建模,转换成网络流的问题。所以网络流问题的难点就是如何建模。