```cpp
/*
总的思路就是找还有哪些路可以走,只要找到新的路,流量就增加了
需要注意的是,这里面反向边的含义,可以大致理解为,找路的过程是随机的,可能找到的不是最优的,
那么,加一条反向边,后面就有可能找到这个反向边来走,这样就相当于弥补了以前的错误,相当于走了正确的道路 */ #include <iostream>
using namespace std;
#include <cstring>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iomanip>
#include <stdlib.h>
#include <unordered_map>
#include <queue>
typedef long long ll;
const int N = 100020, M = 2 * N;
struct Edge
{
ll v, c, ne;
} e[M]; // 存边的结构体,v表示边的终点,c表示剩下的容量,ne表示下一条边在边集中的位置
int idx = 1; /*这里之所以从1开始,是因为这里面要处理反向边,
我们为了方便找到一条边的反向边,
让正向边和对应的反向边在边集数组中相邻,两两配对
也就是add(a,b,c);紧接着add(b,a,0);反向边初始化为0
而我们在这里用i!=0来遍历边,所以0和1这一对就不能用了,
我们存边用e[++idx]={},这样从2和3开始配对
ps:相邻两个数(要求是偶数在前,奇数在后)满足:a^1=b,b^1=a,因为异或是不进位加法
*/
int h[N]; // 链表头节点指针数组,存储的是每个点的第一个出边在边集数组中的位置 int n, m;
int S, T; // 源点和汇点 ll mf[N]; // 从源点到v的路径上的流量上限
ll pre[N]; // 每个节点的前驱边在边集中的位置 void add(int a, int b, int c)
{
e[++idx] = {b, c, h[a]};
h[a] = idx;
} bool bfs() // bfs找从源点到汇点的路径,如果能找到就返回true,否则返回false
{
memset(mf, 0, sizeof mf); // 初始化当前查找的路径的上,从源点到各个节点的流上限
// 同时mf还可以用来判断有没有被遍历
queue<int> q;
q.push(S); // 源点入队 mf[S] = 0x3f3f3f3f; // S到S的流量上限设为“无穷大”,不影响后面求流量上限 while (q.size())
{
auto u = q.front();
q.pop(); for (int i = h[u]; i; i = e[i].ne) // 遍历这个点的出边
{
ll v = e[i].v; // 取出这条边的重点 if (mf[v] == 0 && e[i].c) // 如果这个边的终点还没有被遍历,也就是这个边没有被遍历
//! 并且,这条边的容量还没有被用完,那就可以走这条边
{
mf[v] = min(mf[u], e[i].c); // 那么到v这个边的流量上限就是到u的流量上限和这条边的剩余容量的最小值 pre[v] = i; // 存储前驱边 q.push(v); // v入队 if (v == T)
{
// 如果找到了汇点,那就找到了一个可行的路径,直接返回true
return true;
}
}
}
} return false;
} ll EK() // 用于把可行的流量累加起来
{
ll flow = 0; while (bfs()) // 每次先找一条可行的路径
{
// 如果还找的到
int v = T; // 从汇点反向找到源点,更新本次bfs找到的这条路径上各个边的剩余容量
while (v != S)
{
int i = pre[v]; // 找到这个点的前驱边 e[i].c -= mf[T]; // 从源点到汇点的流量上限就是这条路的流量 e[i ^ 1].c += mf[T]; // 给这个前驱边的反向边增加反向的流量,让后面的尝试可以选择把这条路退回来
v = e[i ^ 1].v; // 反向边的终点就是v的前驱点
}
flow += mf[T];
} return flow;
} int main()
{
cin >> n >> m >> S >> T; for (int i = 1; i <= m; i++)
{
int a, b, c;
cin >> a >> b >> c; add(a, b, c);
add(b, a, 0);
} cout << EK(); return 0; }

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

  1. (通俗易懂小白入门)网络流最大流——EK算法

    网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...

  2. 二分图的最大匹配——最大流EK算法

    序: 既然是个图,并且求边数的最大值.那么这就可以转化为网络流的求最大流问题. 只需要将源点与其中一子集的所有节点相连,汇点与另一子集的所有节点相连,将所有弧的流量限制置为1,那么最大流 == 最大匹 ...

  3. 最大流EK算法/DINIC算法学习

    之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...

  4. 网络流最大流——dinic算法

    前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...

  5. 初探网络流:dinic/EK算法学习笔记

    前记 这些是初一暑假的事: "都快初二了,连网络流都不会,你好菜啊!!!" from 某机房大佬 to 蒟蒻我. flag:--NOIP后要学网络流 咕咕咕------------ ...

  6. 最大流——EK算法

    一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...

  7. [讲解]网络流最大流dinic算法

    网络流最大流算法dinic ps:本文章不适合萌新,我写这个主要是为了复习一些细节,概念介绍比较模糊,建议多刷题去理解 例题:codevs草地排水,方格取数 [抒情一下] 虽然老师说这个多半不考,但是 ...

  8. vector实现最大流EK算法

    序: 在之前的文章中实现了不利用STL实现EK算法,效率也较高.这次我们企图简化代码,减少变量的使用与手写模拟的代码. 注意:vector等STL的container在不开O2优化的时候实现同一个效果 ...

  9. HDU 1532 Drainage Ditches(最大流 EK算法)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用“+=”替 ...

  10. 【转】最大流EK算法

    转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...

随机推荐

  1. 要命的DRG成本核算!

    改开几十年的三座大山之一,鬼见愁的问题.会随着DRG的推进而让平头老百姓过上翻身做主的日子呢!? 对于DRG,首先医保部门需要了解病种成本状况,确定给你结算多少银子.第二,咱们医院靠医保吃饭,那就更需 ...

  2. Spring框架中的单例bean是线程安全的吗?

    1.介绍两个概念 有状态的bean:对象中有实例变量(成员变量),可以保存数据,是非线程安全的 无状态的bean:对象中没有实例变量(成员变量),不能保存数据,可以在多线程环境下共享,是线程安全的 2 ...

  3. Java 21 新特性

    Java 21 是 Java 语言的一次重要更新,引入了若干新的特性,提升了开发者的编程效率和代码质量.本文将详细介绍 Java 21 的新特性,包括基础概念.使用方法.常见实践以及最佳实践. 简介 ...

  4. 话说神奇的content="IE=edge,chrome=1"的meta标签内容

    这是个是IE8的专用标记,用来指定IE8浏览器去模拟某个特定版本的IE浏览器的渲染方式(比如人见人烦的IE6),以此来解决部分兼容问题,例如模拟IE7的具体方式如下: < meta http-e ...

  5. Git常用命令大全:git命令基本用法

    1. 常用的git命令 Git 常用的六个命令是什么? ·"git clone"克隆代码: ·"git log"查看日志: ·"git tag&quo ...

  6. Python实验2 turtle 库绘制进阶图形

    实验任务: 绘制嵌套彩色五角星(大小逐层递减) 设计函数绘制自定义正多边形(边数与颜色参数化) 扩展:实现动态旋转花瓣图案. 源代码:import turtle 绘制嵌套彩色五角星 def neste ...

  7. CTF你真的懂PHP吗--PHP代码审计

    http://ctf5.shiyanbar.com/web/PHP/index.php 就是一个纯代码审计 访问.txt地址撸一把源码 进行分析 <?php $info = "&quo ...

  8. 使用DVC管理大文件变更历史(基于git)

    DVC(Data Version Control) 是一个专门用于管理数据和二进制文件版本控制 的工具,它特别适合那些需要处理大量非文本文件(如图像.视频.模型.数据集等)的项目. 一般地,如果项目中 ...

  9. Gnirehtet —— 通过 USB 让手机共享 PC 网络

    Gnirehtet 使用教程 什么是 Gnirehtet? Gnirehtet("Tethering" 反写)是 Google 开发的开源工具,用于 通过 USB 共享 PC 网络 ...

  10. 制作带sshd功能的centos镜像

    docker run -it --name node1 docker.io/centos bash  创建node1容器 docker exec -it node1 bash 进入node1 yum ...