EK算法模板很好:https://www.cnblogs.com/pk28/p/8039645.html
最大流讲解很好:https://blog.csdn.net/stevensonson/article/details/79177530
一、什么是网络流? 什么是最大流
网络流
(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。网络流的理论和应用在不断发展。而我们今天要讲的就是网络流里的一种常见问题——最大流问题。
最大流问题
(maximum flow
problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力
,使得运输的流量最大
,以取得最好的效果
。求最大流的标号算法最早由福特和福克逊与与1956年提出,20世纪50年代福特(Ford)、(Fulkerson)建立的“网络流理论”,是网络应用的重要组成成分. ——————(来自百度百科)
最大流就是解决从源点
到汇点
的最大流量
问题。
二、网络流中的定义、术语
有相同G = <V, E>中
- 源点:
入度为0
的点(出发点), 图中有唯一的一个源点S
。 - 汇点:
出度为0
的点(结束点), 图中有唯一的一个汇点T
- 容量: 图中每一条弧 e(u,v) 都有一个非负
容量
c(u,v)。
满足上述条件的图G称为网络流图。
记为G = (V,E,C)
流量: 流量是一条弧的实际流过的水量(通常用f(u,v)表示), 流量 一定不大于该弧的容量(f(u,v)<= c(u,v)), 也可以说容量就是该弧流量的上限。
可行流: 只要满足f(u,c)<= c(u,v), 我们就称流量f(u,v)是可行流。
正向弧:从s到t的一条简单路径(又叫迹), 如果边(u,v)与该路径方向相同
叫做,正向弧。
反向弧:从s到t的一条简单路径(又叫迹), 如果边(u,v)与该路径方向相反
叫做,反向弧。
残余网络:计算出图中的每条边上容量与流量之差(称为残余容量),即可得到残余网络。注意由于反向边的存在,残余网络中的边数可能到达原图中边数的两倍。
{残留网络:顾名思义,残留网络就是找完增广路,剩下的网络流图。}
相关问题:
为什么要增加反向边?
因为用bfs寻找增广路时, 会破坏其他路径,也就是这种算法的弊端, 所以增加了
反向边, 可以有反悔的余地。如果反悔,就利用当前的流到a的流量,来退掉一些以往流到a的流量,是这些被退掉的流量能够通过别的路径到达汇点。反向边的作用->
最大流就是解决网络流图
上 从源点
到汇点
的最大流量
问题。
三、最大流算法的讲解:
先看(主要是1. 2. 讲的好)1和2.
1.最大流讲解很好:https://blog.csdn.net/stevensonson/article/details/79177530
2.EK算法模板很好:https://www.cnblogs.com/pk28/p/8039645.html
Dinic 算法:https://blog.csdn.net/u011815404/article/details/86239356
3.最大流算法之Ford-Fulkerson算法与Edmonds–Karp算法:https://blog.csdn.net/yuyilahanbao/article/details/81057818
4.图论的几个算法讲解(含EK ,Ford-fulkerson, Dinic算法, 含时间复杂度)https://blog.csdn.net/llzhh/article/details/52135182
poj1273
EK算法(时间复杂度 O(V*E^2 ))百度百科的讲解
EK算法就是:
(1)通过bfs找增广路;如果找到执行②; 否则结束
(2)计算出增加量, 构造出残留网络(就是 对应边减去增加量,对应边的反向边加上增加量);
(3)重复(1)(2)
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 205;
const int INF = 0x3f3f3f3f;
int r[maxn][maxn]; /**** 残留网络, 初始化为原图 ,邻接矩阵储存***/
bool visit[maxn];/***标记访问过点, 标记数组**/
int pre[maxn];/*****存该节点的前一个被访问的节点****/
int m, n;/**m边 n是点**/
bool bfs(int s, int t) /******寻找一条从s 到 t的增广路, 若存在 返回 true***********/
{
queue<int>q;
memset(pre, -1, sizeof(pre)); /*****初始化 暂时未解读???????????******/
memset(visit, false , sizeof(visit)