前言

EK算法是求网络最大流的最基础的算法,也是比较好理解的一种算法,利用它可以解决绝大多数最大流问题。

但是受到时间复杂度的限制,这种算法常常有TLE的风险

思想

还记得我们在介绍最大流的时候提到的求解思路么?

对一张网络流图,每次找出它的最小的残量(能增广的量),对其进行增广。

没错,EK算法就是利用这种思想来解决问题的

实现

EK算法在实现时,需要对整张图遍历一边。

那我们如何进行遍历呢?BFS还是DFS?

因为DFS的搜索顺序的原因,所以某些毒瘤出题人会构造数据卡你,具体怎么卡应该比较简单,不过为了防止大家成为这种人我就不说啦(#^.^#)

所以我们选用BFS

在对图进行遍历的时候,记录下能进行增广的最大值,同时记录下这个最大值经过了哪些边。

我们遍历完之后对这条增广路上的边进行增广就好啦

代码

题目在这儿

代码里面我对一些重点的地方加了一些注释,如果我没写明白的话欢迎在下方评论:blush:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN=*1e6+;
const int INF=1e8+;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=nc();}
while(c>=''&&c<=''){x=x*+c-'';c=nc();}
return x*f;
}
struct node
{
int u,v,flow,nxt;
}edge[MAXN];
int head[MAXN];
int num=;//注意这里num必须从0开始
inline void add_edge(int x,int y,int z)
{
edge[num].u=x;
edge[num].v=y;
edge[num].flow=z;
edge[num].nxt=head[x];
head[x]=num++;
}
inline void AddEdge(int x,int y,int z)
{
add_edge(x,y,z);
add_edge(y,x,);//注意这里别忘了加反向边
}
int N,M,S,T;
int path[MAXN];//经过的路径
int A[MAXN];//S到该节点的最小流量
inline int EK()
{
int ans=;//最大流
while(true)//不停的找增广路
{
memset(A,,sizeof(A));
queue<int>q;//懒得手写队列了。。。
q.push(S);
A[S]=INF;
while(q.size()!=)
{
int p=q.front();q.pop();
for(int i=head[p];i!=-;i=edge[i].nxt)
{
if(!A[edge[i].v]&&edge[i].flow)
{
path[ edge[i].v ]=i;//记录下经过的路径,方便后期增广
A[edge[i].v]=min(A[p],edge[i].flow);//记录下最小流量
q.push(edge[i].v);
}
}
if(A[T]) break;//一个小优化
}
if(!A[T]) break;//没有可以增广的路径,直接退出
for(int i=T;i!=S;i=edge[path[i]].u)//倒着回去增广
{
edge[path[i]].flow-=A[T];
edge[path[i]^].flow+=A[T];//利用异或运算符寻找反向边,0^1=1 1^1=0
}
ans+=A[T];
}
return ans;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
memset(head,-,sizeof(head));
N=read(),M=read(),S=read(),T=read();
for(int i=;i<=M;i++)
{
int x=read(),y=read(),z=read();
AddEdge(x,y,z);
}
printf("%d", EK() );
return ;
}

性能分析

通过上图不难看出,这种算法的性能还算是不错,

不过你可以到这里提交一下就知道这种算法究竟有多快(man)了

可以证明,这种算法的时间复杂度为$O(n*m^2)$

大体证一下:

我们最坏情况下每次只增广一条边,则需要增广$m-1$次。

在BFS的时候,由于反向弧的存在,最坏情况为$n*m$

总的时间复杂度为$O(n*m^2)$

后记

EK算法到这里就结束了。

不过loj那道题怎么才能过掉呢?

这就要用到我们接下来要讲的其他算法

网络最大流算法—EK算法的更多相关文章

  1. 图论算法-网络最大流【EK;Dinic】

    图论算法-网络最大流模板[EK;Dinic] EK模板 每次找出增广后残量网络中的最小残量增加流量 const int inf=1e9; int n,m,s,t; struct node{int v, ...

  2. 【最大流之ek算法】HDU1532 求最大流

    本来是继续加强最短路的训练,但是遇到了一个最短路 + 最大流的问题,最大流什么鬼,昨天+今天学习了一下,应该对ek算法有所了解,凭借学习后的印象,自己完成并ac了这个最大流的模板题 题目大意:都是图论 ...

  3. 最大流的EK算法模板

    模板题:洛谷p3376 题目大意: 给出一个网络图,以及其源点和汇点,求出其网络最大流. 基本思路: 套模板 EK的时间复杂度O(V*E^2) EK算法思路: 1.通过BFS拓展合法节点(每个节点在本 ...

  4. 一般增广路方法求网络最大流(Ford-Fulkerson算法)

    /* Time:2015-6-18 接触网络流好几天了 写的第一个模版————Ford-Fulkerson算法 作用:求解网络最大流 注意:源点是0 汇点是1 如果题目输入的是1到n 请预处理减1 * ...

  5. HDU1532 网络流最大流【EK算法】(模板题)

    <题目链接> 题目大意: 一个农夫他家的农田每次下雨都会被淹,所以这个农夫就修建了排水系统,还聪明的给每个排水管道设置了最大流量:首先输入两个数n,m ;n为排水管道的数量,m为节点的数量 ...

  6. [学习笔记] 网络最大流的HLPP算法

    #define \(u\)的伴点集合 与\(u\)相隔一条边的且\(u\)能达到的点的集合 \(0x00~ {}~Preface\) \(HLPP(Highest~Label~Preflow~Push ...

  7. poj 1273 Drainage Ditches(最大流,E-K算法)

    一.Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clove ...

  8. Poj(1459),最大流,EK算法

    题目链接:http://poj.org/problem?id=1459 Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Su ...

  9. POJ 1459 Power Network(网络最大流,dinic算法模板题)

    题意:给出n,np,nc,m,n为节点数,np为发电站数,nc为用电厂数,m为边的个数.      接下来给出m个数据(u,v)z,表示w(u,v)允许传输的最大电力为z:np个数据(u)z,表示发电 ...

随机推荐

  1. JS基础整理面试题

    1.DOM和BOM的区别 DOM:document object model;文档对象模型,提供操作页面元素的方法和属性BOM:browser object model;浏览器对象模型,提供一些属性和 ...

  2. mysqldump 导出中文乱码

    命令:mysqldump -uroot -p test > /data/test.sql 导出后的数据库打开是乱码,如下: 开始以为打开的方式不对,就用记事本打开后,用utf-8的编码格式另保存 ...

  3. QEMU KVM Libvirt手册(10): KVM的各种限制

    Overcommits KVM allows for both memory and disk space overcommit. However, hard errors resulting fro ...

  4. 【从零开始搭建自己的.NET Core Api框架】(五)由浅入深详解CORS跨域机制并快速实现

    系列目录 一.  创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...

  5. 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践

    由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...

  6. Hecher学生互助平台(团队项目第一次)

    团队项目作业链接:https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2978 一.团队简介 团队名称:Suc ...

  7. Xapian的内存索引-添加文档

    本文主要记录Xapian的内存索引在添加文档过程中,做了哪些事情. 内容主要为函数执行过程中的流水线. demo代码: Xapian::WritableDatabase db = Xapian::In ...

  8. MySQL查询昨天的数据

    SELECT * FROM `表名` WHERE TO_DAYS(`时间字段名`) = TO_DAYS(NOW()) - 1; 需要前几天的话就在后面减几天.

  9. 简单实现 C# 与 Javascript的兼容

    本文章介绍下自己这刚实现的一个c#与js交互的插件.需求来源于一次与朋友的讨论.主要对话如下: 朋友:最近我想模拟一些数据,来测试我现在写的接口,但手工编写这些测试数据太麻烦了 本人:是啊,.net能 ...

  10. 『数组的最大代价 贪心优化DP』

    数组的最大代价(51nod 1270) Description 数组A包含N个元素A1, A2......AN.数组B包含N个元素B1, B2......BN.并且数组A中的每一个元素Ai,都满足1 ...