以前在oi中见到网络流的题都是直接跳过,由于本蒟蒻的理解能力太弱,导致网络流的学习不断推迟甚至被安排在了tarjan之后,原本计划于学习完最短路后就来学网络流的想法也随之破灭,在看完众多大佬

的博客后,我发现我不怎么能看懂(因为我自己太菜了),所以特来写一篇整理一下自己所学到的.

常见的网络流算法根据优化程度有FF<EK<Dinic<ISAP,由于后两种算法比较复杂,我至今也没有很好的理解,今天只要是我自己的一些对EK的理解.

首先需要了解一下什么是网络最大流:

网络流:所有弧上流量的集合f={f(u,v)},称为该容量网络的一个网络流.

  • 定义:带权的有向图G=(V,E),满足以下条件,则称为网络流图(flow network):

    1. 仅有一个入度为0的顶点s,称s为源点
    2. 仅有一个出度为0的顶点t,称t为汇点
    3. 每条边的权值都为非负数,称为该边的容量,记作c(i,j)。

    弧的流量:通过容量网络G中每条弧< u,v>,上的实际流量(简称流量),记为f(u,v);

网络流具有以下性质:

1.边所容纳的流量<=该边的最大容量.

2.反对称性,即f[u][v]=-f[v][u].

3.从源点流出的流量总是等于汇点汇聚的流量,对于其他的普通点来说,入度来的流量和等于出度出去的流量和.

最大网络流:网络流量图G中,最大的可行流称为网络最大流

我们定义:
源点:只有流出去的点
汇点:只有流进来的点
流量:一条边上流过的流量
容量:一条边上可供流过的最大流量
残量:一条边上的容量-流量

增广路:找到一条从源点到汇点的路径,使得路径上任意一条边的残量>0(注意是大于而不是大于等于,这意味着这条边还可以分配流量),这条路径便称为增广路

EK:不断找到一条起点到终点的路径,若有,找出这条路径上每一条边的最小值,然后将这条路上的每一条正向边减去这条路的流量,再在这条路上的每一条反向边加上这条边的流量,再在剩下的图上寻找新的路径,使总流量增加。然后形成新的图,再寻找新路径…..直到找不到从起点到终点的路径为止,最大流就算出来了。

#include<bits/stdc++.h>
using namespace std;
int st[],vis[],n,m,s,flow[],maxflow,t,x,y,z,tot=-,pre[],q[];
struct node
{
int from,to,val,last;
/*
from记录起点
to记录重点
val记录这条边的流量
last记录起点和当前这条边的起点一样的边的序号
*/
}e[];
int mn(int x,int y)
{
if(x>y)
return y;
return x;
}
void add(int f,int t,int v)
{//链式前向星
tot++;//当前这条边的序号
e[tot].from=f;
e[tot].to=t;
e[tot].val=v;
e[tot].last=st[f];
st[f]=tot;
return ;
}
bool bfs(int s,int m)//寻找从起点到终点的路径
{
int t=,h=;
for(int i=;i<=n;i++)
{
vis[i]=-;//一开始把所有的点(包括起点和终点)标志为没有走过
pre[i]=-;//记录上一条到达i点的边的起点的编号
}
t++;
q[t]=s;//将起点入队
vis[s]=;
flow[s]=;
while(t>=h)
{
int u=q[h];//拿出队首
vis[u]=;//当前的队首标志为不在队列里
h++;//踢出队首
for(int i=st[u];i!=;i=e[i].last)
{
int v=e[i].to;
if(e[i].val!= && vis[v]==-)//如果当前遍历到的点不在队列里(避免重复入队)就入队
{
flow[v]=mn(flow[u],e[i].val);//更新这条路径的流量(比较,求出最小值)
pre[v]=i;//编号为i的这条边到达了v点,更新pre[v]
t++;//入队
q[t]=v; //将
vis[v]=u;
}
}
}
if(vis[m]!=-)//从当前点s可以走到点m
return true;
return false;//如果运行到了这里,说明再也找不到从起点到终点的路了
}
void update(int s,int t)//一个回溯过程
{//如果能进这个函数,说明从当前点s可以走到点t
int now=t;//从终点往回查找
while(now!=s)//如果当前回溯到的点不是起点
{//继续找
int i=pre[now];
e[i].val-=flow[t];//正向边加上这条边的流量
e[i^].val+=flow[t];//建反向边,减去这条边的流量
now=e[i].from;//更新当前回溯到的点
}
maxflow+=flow[t];//加上当前这条边的流量
}
void EK(int s,int t)
{
maxflow=;//重置最大流
while(bfs(s,t)==true)//如果当前找得到一条从起点到终点的路
update(s,t);//加上这条路的流量
}
int main()
{
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
add(x,y,z);//建正向边
add(y,x,);//建反向边
}
EK(s,t);//求最大流
printf("%d",maxflow);//输出
return ;
}

网络最大流(EK)的更多相关文章

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

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

  2. 网络最大流算法—EK算法

    前言 EK算法是求网络最大流的最基础的算法,也是比较好理解的一种算法,利用它可以解决绝大多数最大流问题. 但是受到时间复杂度的限制,这种算法常常有TLE的风险 思想 还记得我们在介绍最大流的时候提到的 ...

  3. luogu P3376 【模板】网络最大流(no)ek

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  4. 洛谷 P3376【模板】网络最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  5. 网络最大流的(Edmond Karp)算法

    容量网络:在有向图D=(V,A),指定一个点为发点,记作 s,指定另一个点为收点,记作 t,其余点叫作中间点.对于A的每条弧(Vi,Ai),都对应一个权数 C ≥0,称为弧(Vi , Ai)的容量,将 ...

  6. P3376 【模板】网络最大流(luogu)

    P3376 [模板]网络最大流(luogu) 最大流的dinic算法模板(采取了多种优化) 优化 时间 inline+当前弧+炸点+多路增广 174ms no 当前弧 175ms no 炸点 249 ...

  7. 网络最大流算法—Dinic算法及优化

    前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. ...

  8. 『题解』洛谷P3376 【模板】网络最大流

    Problem Portal Portal1:Luogu Description 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. Input 第一行包含四个正整数\(N,M,S,T\),分 ...

  9. 洛谷 P3376 【模板】网络最大流 题解

    今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值. EK 算法 #include< ...

随机推荐

  1. Web 3D是否需要WebAssembly?

    大家好,本文讨论了Web 3D是否需要WebAssembly,结论是: 对于使用原生3D技术的程序员,需要: 对于使用Javascript语言的前端程序员,不需要,有其它方法可以达到接近WebAssd ...

  2. Java面向对象之异常【一】

    目录 Java面向对象之异常[一] 异常的继承体系 Error Exception 异常是否受检 unchecked exceptions(不受检异常) checked exceptions(受检异常 ...

  3. 快速掌握—HTML快速实现自定义Input开关

    HTML <input id="customSwitch" type="checkbox" /> <label for="custo ...

  4. CVE-2019-0708远程桌面服务远程执行代码漏洞exp利用过程

    CVE-2019-0708远程桌面服务远程执行代码漏洞 上边这洞是啥我就不多说了,描述类的自行百度. 受影响系统版本范围: Windows Server 2008 R2 Windows Server ...

  5. 2、Vue实战-配置篇-npm配置

    引言: 如果刚开始使用 vue 并不了解 nodejs.npm 相关知识可以看我上一篇的实践,快速入门了解实战知识树. Vue实战-入门篇 上篇反思: 1.新的关注点:开发 vue 模板.如何使用本地 ...

  6. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  7. Redis常用命令详细介绍

    一.字符串 字符串键是Redis最基本的键值对类型,将一个单独的键和一个单独的值关联起来.通过字符串键,不仅可以存储和读取字符串,如果输入能被解释为整数和浮点数,还能执行自增或自减操作. 1.SET: ...

  8. 1.HelloWorld 仪式感

    HelloWorld: 1.随便新建一个文件夹,存放代码. 2.新建一个java文件 文件后缀改为 .java Hello.java 系统可能没显示文件后缀名,我们需要手动打开 3.编写代码 publ ...

  9. Java入门 - 语言基础 - 06.变量类型

    原文地址:http://www.work100.net/training/java-variable-type.html 更多教程:光束云 - 免费课程 变量类型 序号 文内章节 视频 1 概述 2 ...

  10. Java入门 - 面向对象 - 05.封装

    原文地址:http://www.work100.net/training/java-encapsulation.html 更多教程:光束云 - 免费课程 封装 序号 文内章节 视频 1 概述 2 封装 ...