前言
网络中的交换机能够实时的进行数据的接收转发,如果我们要从A地传送一组数据报到达B地,在不存在丢包的前提下一次分发B地最多能接收多少报文呢?这种网络模型可以利用水流的模拟来解决,学名称网络流。
算法介绍
总所周知,水往低处流。每个节点可以抽象成一个木桶,所以一次能通过的流量是有瓶颈的,根据木桶原理,我们每次可以流过的流量取决于前面最小的弧。这里很容易走进一个误区,贪心地每次去找下一条路径的最大的流过去,这是错误的,至于为什么很容易想到一些例子推翻,试想,一个水流到达一个分叉路假设水流足够肯定是两边都会有水灌下去。
于是,我们算法地核心思路是:
- 每次找一条增广路,然后灌水下去,至于灌的水为: a [ e . t o ] = m i n ( a [ e . f r o m ] , e . c a p − e . f l o w ) a[e.to]=min(a[e.from], e.cap-e.flow) a[e.to]=min(a[e.from],e.cap−e.flow),相当于之前的水的最大和当前的残余容量找一个最小的更新,这是木桶原理(水多了也只能接收我容量内的,水不够我容量的也只有那么多让你接收)。
- 这样最终到达汇点就说明找到一条增广路了,更新后,利用反向弧来减少由于这次的流量占据的流量,相当于缩小容量
- 当找不到增广路后显然找到最大流,算法结束
实现
#include <bits/stdc++.h>
using namespace std;
/**
* 最大流增广路EK算法
*/
namespace EK {
const int inf = 0x3f3f3f3f;</