网络流-EK算法(保姆级教学)

本文引用董晓算法的部分图片。

一些不能带入纸质资料的竞赛,网络流纳入考纲。

因为需要默写,想来也不会考默写dinic这种算法难倒大家,只需要快速敲对EK算法就行了。

EK算法能在O(n*m^2)的复杂度内解决最大流问题,其中最大流就是源点到汇点的最大流量。

一般来说起点的流量是无穷,每条边有一个最大流容量c,再定义当前边已经流过了容量f。

很显然,网络流模型必须满足每条边的f<=c,同时每条边的流入量必须等于流出量。

EK算法的过程如下:

不断尝试,从源点找一条到达汇点流量大于0的路径,我们又称这条路为增广路

如图就是一条增广路。(图中5/5表示f/c)

但是确定一条增广路后,我们找新的增广路,就会因为旧的路径已经存在而被阻挡。

这时候我们就需要建立反向边。

反向边的意义在于给了之前存在的路径一个反悔的机会。

如图所示,假设右下角是汇点,左图是一条黑色的增广路,中间图片中,新增了一条红色的增广路,因为建立了反向边,所以红色路径可以正常到达汇点。等效成右图所示的结果,这样最大流就从5变成10了,其实就是通过反向边来达到旧边给新边让路的效果。

代码如下所示:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1e3+5;
int a[N][N];
int mf[N],isque[N];
//mf表示到该点的流量 
int pre[N];
int n,m,e;
int bfs(int su,int sv){memset(mf,0,sizeof(mf));for (int i=0;i<=n+m+1;i++) mf[i]=0;for (int i=0;i<=n+m+1;i++) isque[i]=0;mf[su]=INF;queue<int> q;q.push(su);isque[su]=true;pre[su]=-1;while(!q.empty()){int u=q.front();q.pop();isque[u]=false;for (int v=0;v<=n+m+1;v++){if (u==v) continue;if (mf[v]<min(mf[u],a[u][v])){mf[v]=min(mf[u],a[u][v]);pre[v]=u;if (mf[sv]!=0)	return true;if (isque[v]==false){q.push(v);isque[v]=true;}}}}return false;
}
int ek(int su,int sv){int ans=0;while(bfs(su,sv)){ans+=mf[sv];int p=sv;while(pre[p]!=-1){a[p][pre[p]]+=mf[sv];a[pre[p]][p]-=mf[sv];p=pre[p];}}return ans;
}
void work(){cin>>n>>m>>e;for (int i=1;i<=n;i++){a[0][i]=1;a[i][0]=0;}for (int i=1;i<=m;i++){a[i+n][n+m+1]=1;a[n+m+1][i+n]=0;}for (int i=1;i<=e;i++){int u,v;cin>>u>>v;a[u][v+n]=1;a[v+n][u]=0;}cout<<ek(0,n+m+1)<<"\n";
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);work();return 0;
} 

其中用到了一个BFS和一个DFS(ek)。

BFS在不断找增广路(从源点找一条到达汇点流量大于0的路径),DFS把找到的增广路的流量确定下来,表示到边上,减少对应的容量,并给反向边增加相同的容量(能过去多少就能反悔多少)。

图的存储用邻接矩阵表示(反正都用EK算法了qwq,就更简单一点吧)。

BFS不断找增广路,其中套了一个SPFA的队列优化。mf数组表示到该点的流量为多少,因为需要不断找增广路,并把增广路得到的路径确定到边权的f(已经流过了容量),所以每次确定完成后mf数组就不再需要了,所以每次开始BFS之前要重新置为0。

其中有这个代码:

if (mf[v]<min(mf[u],a[u][v])){mf[v]=min(mf[u],a[u][v]);
}

mf[u]表示前面的点u最多给后面的点v多少流量,a[u][v]邻接矩阵表示这个管子最多承受多少流量,两者的较小值才是v点能过去的最大流量(此处贪心的想,因为要求最大流,所以肯定v点流量越大越好)

这里可能会有一个比较疑惑的点,那既然u到达了v,mf[v]更新了流量,为了满足每条边的流入量必须等于流出量,u点的mf数组不是应该更新吗?为什么代码里没有更新。如果不更新的话,假如mf[u]=5,岂不是u的每一个mf[v]都会被设置成5?

这是因为BFS的意义是找到一条可行的增广路,而不是真的全部遍历完才把结果抛给DFS。这样一旦有一条路径到达汇点,就一定仅仅只会有一条路径(感觉说了句废话),不会出现重复的情况。

这里可以发现mf的意义不是当前点的实际最大流,而是为了找到一条尽可能大且可行的流服务的。

感谢观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wpf 附加属性 RegisterAttached 内容属性

// // 摘要: // 选中时展示的元素 public static readonly DependencyProperty CheckedElementProperty DependencyProperty.RegisterAttached("CheckedElement", typeof(object), typeof(StatusSwitchElement), new PropertyMetadata((object)null…

java加载文件初始化数据

对于一些数据量不大的配置类数据&#xff0c;放到数据库中占用数据库资源&#xff0c;可以放到代码中维护。比如 &#xff08;1&#xff09;字段少业务单一&#xff1a;做成枚举&#xff1b; &#xff08;2&#xff09;字段多业务复杂&#xff1a;则可以放到文件中维护&#…

【Linux小命令】一文讲清ldd命令及使用场景

一文讲清ldd命令及使用场景 前言下面进入正题&#xff1a;ldd命令 前言 博主今天ubuntu编译go项目出来的一个可执行文件&#xff0c;放centos运行发现居然依赖于XXlib库。然后我一下就想到两个系统库版本不一致&#xff0c;重编。换系统&#xff0c;导项目&#xff0c;配环境……

从新手到高手:彻底掌握MySQL表死锁

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 从新手到高手&#xff1a;彻底掌握MySQL表死锁 前言什么是死锁mysql死锁的原因1. 互斥资源的竞争…

备份操作系统

在VMware中备份方式&#xff1a;快照和克隆 1.快照&#xff1a;短期备份&#xff0c;频繁备份 快照&#xff1a;又称还原点&#xff0c;就是保存在拍照时&#xff0c;系统状态。在后期的时候可以恢复 2.克隆&#xff1a;长期备份 克隆&#xff1a;就是复制的意思&#xff0…

maven仓库的作用以及安装 , DEA配置本地Maven

ay12-maven 主要内容 Maven的作用Maven仓库的作用Maven的坐标概念Maven的安装IDEA配置本地Maven 一、maven概述 1.1、项目开发中的问题 1、我的项目依赖一些jar包&#xff0c;我把他们放在哪里&#xff1f;直接拷贝到项目的lib文件夹中?如果我开发的第二个项目还是需要上面…

网管工作实践_02_IP/MAC地址管理工具

1、ipconfig命令格式及参数 ipconfig是内置于Windows的TCP/IP应用程序&#xff0c;用于显示本地计算机网络适配器的MAC地址和IP地址等配置信息&#xff0c;这些信息一般用来榆验手动配置的TCP/IP设置是否正确。当在网络中使用 DHCP服务时&#xff0c;IPConfig可以检测计算机中分…

006 动态数组(lua)

文章目录 初步准备实际应用 在Lua中&#xff0c;没有类的概念&#xff0c;因为它是基于原型的语言。不过&#xff0c;我们可以使用表&#xff08;table&#xff09;来模拟类和对象 Lua中的数组索引是从1开始的&#xff0c;而不是从0开始&#xff0c; Lua的表是动态大小的&#…

DigitalOcean 推出 Opensearch 托管服务,易用且强大的日志洞察与分析工具

DigitalOcean 宣布推出 DigitalOcean 的 Opensearch托管服务&#xff0c;这是一款专为深入的日志分析、简化故障排查和优化应用性能而设计的全面的解决方案。 简单介绍一下 Opensearch 这里先给不了解 Opensearch 的用户简单介绍一下。OpenSearch 是从 Elasticsearch 的一个相…

提升网络速度的几种有效方法

在数字化时代&#xff0c;网络速度对于我们的日常生活和工作至关重要。无论是观看高清视频、在线游戏&#xff0c;还是进行视频会议&#xff0c;快速稳定的网络连接都是不可或缺的。如果你发现自己当前的网络速度不尽如人意&#xff0c;那么不妨尝试以下几种方法来提升它。 升…

6.26.8 基于多视角深度卷积神经网络的高分辨率乳腺癌筛查

1. 介绍 1.1 乳腺癌筛查 开发了一种新的DCN&#xff0c;它能够处理乳房x线摄影筛查的多个视图&#xff0c;并利用大分辨率图像而不缩小。将这种DCN称为多视图深度卷积网络(MV-DCN)。网络学习预测放射科医生的评估&#xff0c;将传入的样本分类为BI-RADS 0(“不完整”)&#xf…

网络问题排障专题-AF网络问题排障

目录 一、数据交换基本原理 1、ARP协议工作原理 数据包如图&#xff1a; 2、二层交换工作原理 简述核心概念&#xff1a; 二层交换原理-VLAN标签 3、三层交换工作原理 二、AF各种部署模式数据转发流程 1、路由模式数据转发流程 三、分层/分组逐一案例讲解 1、问题现…

对于 PHP 开发的 Web 应用,怎样有效地防止 SQL 注入攻击?

防止 SQL 注入攻击是在 PHP 开发的 Web 应用中非常重要的安全措施之一。下面是一些有效的防止 SQL 注入攻击的方法&#xff1a; 使用参数化查询和预处理语句&#xff1a;使用参数化查询能够将用户输入的数据与 SQL 查询分离&#xff0c;从而避免 SQL 注入攻击。使用预处理语句可…

免费分享一套SpringBoot+Vue在线水果(销售)商城管理系统【论文+源码+SQL脚本】,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue在线水果(销售)商城管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue在线水果(销售)商城管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue在线水果(销售)商…

Android高级面试_8_热修补插件化等

Android 高级面试&#xff1a;插件化和热修复相关 1、dex 和 class 文件结构 class 是 JVM 可以执行的文件类型&#xff0c;由 javac 编译生成&#xff1b;dex 是 DVM 执行的文件类型&#xff0c;由 dx 编译生成。 class 文件结构的特点&#xff1a; 是一种 8 位二进制字节…

探索Facebook的未来世界:数字社交的演进之路

在数字化和全球化的浪潮中&#xff0c;社交网络如Facebook已经成为了人们日常生活不可或缺的一部分。然而&#xff0c;随着技术的迅猛发展和用户需求的不断变化&#xff0c;Facebook正在经历着社交平台的演进之路。本文将探索Facebook的未来世界&#xff0c;分析数字社交的发展…

CP AUTOSAR标准之KeyManager(AUTOSAR_CP_SWS_KeyManager)(更新中……)

1 简介和功能概述 该规范描述了AUTOSAR基础软件模块< KeyManager >的功能、API和配置。   AUTOSAR KeyM模块由两个子模块组成,即加密密钥子模块和证书子模块,如[1]“AUTOSAR对加密堆栈的要求”所要求。   加密密钥子模块提供API和配置项来引入或更新预定义的加密密…

技术选型新趋势:中小型企业如何选用高效CRM“小型应用”进行客户管理

众所周知&#xff0c;CRM应用通过优化客户信息管理、提升销售效率、提高客户服务质量、实现市场营销自动化以及支持数据分析与决策等方面&#xff0c;为企业创造更大的价值&#xff0c;提升企业的竞争力和市场份额。 对初创型、中小型企业来说&#xff0c;使用合适的CRM应用至…

【LLVM】学习使用PGO优化

笔者在查看PGO优化时看到了本站的这篇文章&#xff0c;其中代码和命令行部分贴上了序号&#xff0c;且命令行带上了$符号&#xff0c;不便于读者调试。 遂将代码重新整理到gitee&#xff0c;链接在此。 汇编代码分析 目前笔者使用的llvm版本为llvm-19&#xff0c;主要改动发生…

RK3588编译环境配置

安装Ubuntu18.04 安装Ubuntu请参考其他教程 安装vmware-tools 如果vmware版本过低&#xff0c;vmware-tools安装可能会出现各种问题。 建议直接用apt-get install安装vmware-tools sudo apt-get update sudo apt-get install open-vm-tools open-vm-tools-desktop vmware-…