网络流-EK求最大流

2021.8.17

网络流最大流解决什么问题?

网络流(network-flows)是一种类比水流的解决问题方法(摘自百度百科),最大流是求源点到汇点最大流量的方法。

算法原理

已知起点到终点,很容易想到深搜\广搜求最大值的方式,但是,在最大流问题中,会出现如下情况:

假设1为源点,4为汇点,若对其进行搜索,路径可能有1->2->3->4,随后标记数组有如下标记:

那么,此时,流经1-2线路的水流,汇入了3号节点最终流向4号节点,此时3-4路径已经被灌满,2-4路径没有水流流入,最终汇入汇点的水流量为1。

但是,对于上述情况,最大流应该是如下情形:

此时汇点流入流量为2.

那么,在建图顺序位置时,如何计算出最大的流量?

退回流量,构建增广路径,当流量汇入其他渠道并且有部分无法汇入汇点,那么就代表其应该回到原渠道,按照原渠道走,但是搜索起来肯定难以实现,因此需要建立一条相反的路径,让流过去的水流能有机会返回原来的渠道,并且最多返回流过去的水流。(不管水流走在哪里,只要流入汇点即可,不必求出其准确的路径)如下图:

如此,在1-3路径中的水流流入3号节点时,可以通过2-3路径流回2号节点,再从2-4路径流入4号汇点,此时便可得最大流量为2.(若1-3为2,则也只能退回1).

但是通常情况下,退流一次并不会得到最大流,因此需要多次搜索多次退流。在EK求最大流中,每次选择在部分流量汇入汇点后,对路径的可行流进行更改,构建增广路径。此时图中每个点的残留量不影响结果,因再次搜索时只计算从源点流出的流量。

对其搜索时,正常进行搜索即可:

bool bfs() {queue<int>q;memset(vis, 0, sizeof vis);q.emplace(S); vis[S] = true, d[S] = 0x3f3f3f3f;while (!q.empty()) {int t = q.front(); q.pop();for (int i = head[t]; !i; i = nexte[i]) {int k = to[i];if (!vis[k] && wei[i]) {vis[k] = 1;d[k] = min(d[t], wei[i]);pre[k] = i;if (k == T)return true;q.emplace(k);}}}return false;
}

其中,d数组记录路径最多流过的流量,pre数组记录路径编号,当成功汇入汇点,则跳出。

每次对路径进行更新时,则对上一步搜索到的路径进行退流:

int EK() {int res = 0;while (bfs()) {//搜索直到没有可行流res += d[T];for (int i = T; i != S; i = to[pre[i] ^ 1])//建图时,反向边编号比正向边多1wei[pre[i]] -= d[T], wei[pre[i] ^ 1] += d[T];//构建增广路径}return res;
}

最终返回的res即为最大流。
注:正向路径同样要减去相应的流量大小,因路径已经被部分或全部占用。

模板代码

代码

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
#include<string.h>
#include<queue>using namespace std;int nexte[20005], wei[20005], to[20005], head[20005];
int n, m, S, T;
int idx;
int pre[20005], d[20005];
bool vis[20005];void addedge(int u, int v, int c) {to[idx] = v, wei[idx] = c, nexte[idx] = head[u], head[u] = idx++;to[idx] = u, wei[idx] = 0, nexte[idx] = head[v], head[v] = idx++;
}bool bfs() {queue<int>q;memset(vis, 0, sizeof vis);q.emplace(S); vis[S] = true, d[S] = 0x3f3f3f3f;while (!q.empty()) {int t = q.front(); q.pop();for (int i = head[t]; !i; i = nexte[i]) {int k = to[i];if (!vis[k] && wei[i]) {d[k] = min(d[t], wei[i]), pre[k] = i;if (k == T)return true;q.emplace(k);vis[k] = 1;}}}return false;
}int EK() {int res = 0;while (bfs()) {res += d[T];for (int i = T; i != S; i = to[pre[i] ^ 1])wei[pre[i]] -= d[T], wei[pre[i] ^ 1] += d[T];}return res;
}int main() {cin >> n >> m >> S >> T;memset(head, -1, sizeof head);for (int i = 0; i < m; i++){int a, b, c;cin >> a >> b >> c;addedge(a, b, c);}cout << EK() << endl;return 0;
}

网络流-EK求最大流相关推荐

  1. 网络流-Dinic求最大流(仅做自己复习,写的很不清楚)

    网络流-Dinic求最大流 2021.8.18 原理:网络流-EK求最大流 在Dinic求最大流中,d数组变成了步数的记录,pre数组变成了对其上一条路径的记录. bool bfs() {queue& ...

  2. 【模板】EK求最大流、dinic求最大流

    ACM模板 目录 概念 EK算法 Dinic算法 概念 yxc老师的部分总结 基本概念 1.1 流网络,不考虑反向边 1.2 可行流,不考虑反向边 1.2.1 两个条件:容量限制.流量守恒 1.2.2 ...

  3. POJ 1966 Cable TV Network【无向图点连通度 最小割 E-K算法求最大流】

    题目描述: 给你一个无向图,问你最少删掉几个点,使这个图成不连通. 解题报告: 概念 (1)一个具有 N 个顶点的图,在去掉任意 k-1 个顶点后 (1<=K<=N) 所得的子图仍连通, ...

  4. 网络流问题:最大流及其算法

    一.概念引入 首先要先清楚最大流的含义,就是说从源点到经过的所有路径的最终到达汇点的所有流量和. 流网络G=(V,E)是一个有向图,其中每条边(u,v)∈E均有一个非负容量c(u,v)>=0.如 ...

  5. 网络流--最小费用最大流 (理解)

    1.什么是最小费用最大流问题 上篇文章我们讲解了最大流问题,那什么是最小费用最大流呢?听名字就可以看出,我们要在满足最大流的同时找到达成最大流的最小费用. 对于一个网络流,最大流是一定的,但是组成最大 ...

  6. Dinic求最大流/最小割

    o(v^2*E) 建图时建一条流量为0的反向边,正向边每减去流量f,反向边增加流量f.对于无向图当做两条边. cap:每条边最大流量 建图后: 调用DINIC():用bfs()为每个节点进行层次编号, ...

  7. 「学习笔记」ISAP求最大流

    ISAP学习笔记 ISAP是OI中求最大流的常用方法之一.相对于Dinic,ISAP的速度提升了很多,但编码复杂度也上升了不少. 约定 采用邻接表存储图,对于每条弧,增加一条容量为0的逆向边. d数组 ...

  8. 网络流----最小费用最大流(EK+SPFA)

    先来介绍一下什么是费用流(部分内容参考bilibili董晓算法) 给定一个网络G=(V,E),每条边有容量限制w(u,v),还有单位流量的费用c(u,v). 当(u,v)的流量为f(u,v)时,需要花 ...

  9. 网络流专题(最大流与费用流)(一)

    流量网络 • 想要将一些水从S运到T,必须经过一些水站,链接水站的是管道,每条管道都有它的最大能容纳的水量,求最多S到T能流多少流量. 基本概念 • 这是一个典型的网络流模型.我们先了解网络流的有关定 ...

最新文章

  1. WinXp安装Oracle 11g Express Edition
  2. tensorflow实践
  3. 如何使用JavaScript更改元素的类?
  4. 操作系统的初始化流程简图
  5. VS2013中提示:没有可放置在工具箱上的组件
  6. LeetCode 744. Find Smallest Letter Greater Than Target (时间复杂度O(n))
  7. [BUUCTF-pwn]——suctf_2018_stack
  8. Nginx 之一:编译安装nginx 1.8.1 及配置
  9. 利用计算机解决鸡兔同笼问题,利用极限思想解决复杂鸡兔同笼问题
  10. Mac/Linux/Win使用scrcpy投屏
  11. 使用ExMerge工具管理Exchange用户邮箱。
  12. script脚本中写不写$(document).ready(function() {});的差别
  13. A*算法收敛最优点的简单证明
  14. 安装Lync Server 2013
  15. 谁分配谁释放HEAP
  16. Linux命令拆分csv文件,linux – 如何剪切CSV文件
  17. 程序员:职业很抓狂!前途很迷茫?送你破解困境秘籍!
  18. 前端杂烩——在工作,在思考,在沉淀
  19. java实现订单轨迹_B端零售业:订单轨迹日志功能设计思考
  20. ISIS与OSPF区别

热门文章

  1. CSS基础(part4)--CSS的层叠性继承性优先级
  2. 不要再把 pp 写出 % 了。
  3. SKlearn参数详解—随机森林
  4. 本地启动 SAP Commerce Cloud(Hybris) 产生的五个 Java 进程
  5. 内容分发网络 - Content Delivery Network 学习笔记
  6. SAP Commerce Cloud UI 的用户会话管理
  7. 什么是 SAP UI5 的 Component-preload.js, 什么是Minification和Ugification
  8. SAP Cloud for Customer UI Designer里如何消费Object Value Selector(OVS)
  9. scss里父选择器的标识符
  10. Trial accounts of SAP Cloud Platform do not provide an Identity Authentication tenant