以前在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. 1078 字符串压缩与解压 (20分)C语言

    文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示.例如 ccccc 就用 5c 来表示.如果字符没有重复,就原样输出.例如 ...

  2. mysql-5.7.9-winx64遇坑记

    昨天在mysql5.0上导入sql文件时,一直卡在一个地方报错,也没仔细分析,认为应该是mysql版本太低不支持这个语法而已.遂决心下载一个最新版本的mysql,却浑然不知前面无数的坑已经埋伏好了在等 ...

  3. react与redux的一点心得(理解能力有限,蜗牛进度)

    Redux是一款状态管理库,并且提供了react-redux库来与React亲密配合, 但是总是傻傻分不清楚这2者提供的API和相应的关系.这篇文章就来理一理. 如果要用一句话来概括Redux,那么可 ...

  4. OpenStack Identity API v3 (CURRENT)

    Table Of Contents Identity API v3 (CURRENT) Authentication and token management Password authenticat ...

  5. P2756 飞行员配对方案问题 二分图匹配 匈牙利算法

    题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外 ...

  6. springboot整合@Scheduled定时任务的使用

    1.启动类里面添加注解@EnableScheduling ,例如: @SpringBootApplication@EnableScheduling@MapperScan("com.examp ...

  7. Linux初始化Git环境

    第一步:设置Git全局用户名和邮箱 git config --global user.name "你的用户名" git config --global user.email &qu ...

  8. 2019CSP复赛游记

    Day 0 作为一个初三的小蒟蒻…… 什么算法都不会打…… 做一道LCA+生成树的图论题调了两个小时…… 明日裸考…… Day 1 Morning 买了两个士力架,带了一盒牛奶,准备在考场上食用(这个 ...

  9. importlib 根据字符串导入模块

    应用: Django中间件,rest framework 组件的全局配置文件 import importlib path = "abc.def.foo" module_path,c ...

  10. 【转】在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)

    原文:http://www.cyqdata.com/cnblogs/article-detail-35876# 背景 在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件 ...