前言

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. 《C#与.NET程序员面试宝典》学习札记

    第2章 .NET概述 2.1-6~ .Net Framework / CLR / IL / Assembly IL:中间语言代码,不同语言(如C#,VB)的基于CLR的编译器编译生成的中间语言字节码, ...

  2. phpcms2008远程代码执行漏洞

    phpcms2008远程代码执行漏洞 描述: 近日,互联网爆出PHPCMS2008代码注入漏洞(CVE-2018-19127).攻击者利用该漏洞,可在未授权的情况下实现对网站文件的写入.该漏洞危害程度 ...

  3. [Swift]LeetCode72. 编辑距离 | Edit Distance

    Given two words word1 and word2, find the minimum number of operations required to convert word1 to  ...

  4. 【视频】使用ASP.NET Core开发GraphQL服务

    GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL来自Facebook,它于2012年开始开发,2015年开源. GraphQL与编程语言无关,可以使用很 ...

  5. Python内置函数(9)——callable

    英文文档: callable(object) Return True if the object argument appears callable, False if not. If this re ...

  6. Python内置函数(50)——print

    英文文档: print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) Print objects to the text str ...

  7. vue+cordova构建跨平台应用集成并使用Cordova plugin

    安装 //安装 vue-cil npm install --global vue-cli //安装cordova npm i cordova -g cordova 新建项目 //新建cordova 项 ...

  8. 跳槽 & 思维导图

    个人博客原文: 跳槽 & 思维导图 今年的冬天有点"冷".给大家来点实在的东西. 不知道大家在跳槽的时候是怎么做的?直接投简历面试?还是准备了一段时间,复习一波知识点后再投 ...

  9. 【Zara原创】SqlSugar4轻量级ORM框架的使用指南

    前言:sqlSugar出生已经有3年之久了,从1.0到现在的4.x的版本,为了以后方便使用SqlSugar,所以特意花了2个小时来叙述它. 关于SqlSugar 性能:性能最好的ORM之一,具有超越D ...

  10. Vuex的基本概念、项目搭建、入坑点

    前言:Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化. Vuex的四大核心 1.state 驱 ...