网络流(二) 最大流算法的实现

网络流——最大流EK算法讲解 好了,这是第二篇博客了,如第一篇所述,来讲一讲刚刚理解的网络流。因为本人只会EK算法,所以先讲这个算法。 什么是网络流??? 读者们刚接触这个知识可能会有点蒙,不,可能是非常蒙。虽然本蒟蒻也只是懵懵懂 如最短路,我想即使先不学,手算也能将一个简单的图求出来。 但是遇到网络流——最大流,那恐怕不是那么好算,反正一开始给我算我也只是一头雾水。(有可能是本人太弱了,各位大佬请谅解)给个图(感谢某位大佬的... 阅读详情

嗯接着前篇…有了前面的原理铺垫,接下来的可能会简单一些…?
FF看见烦,SAP不想学。
所以只剩下EK和Dinic了。
模板题:luogu3376


Edmond-Karp算法

基本上上把EK的queue改成stack就成了FF,所以这里不讨论FF的问题。
先贴代码,然后再说一说其含义。

#include <bits/stdc++.h>
using namespace std;
#define MAXN 100003
struct node{
    int fr, to, va; //从fr到to有一条权值为v的边
    int nxt;
}edge[MAXN];
int cnt, head[MAXN];
inline void read(int &x) {
    x = 0; char c = getchar();
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
} 
inline void add_edge(int u, int v, int w) { //邻接表存边
    edge[cnt].fr = u, edge[cnt].to = v, edge[cnt].va = w;
    edge[cnt].nxt = head[u], head[u] = cnt++;
    edge[cnt].fr = v, edge[cnt].to = u, edge[cnt].va = 0; 
    edge[cnt].nxt = head[v], head[v] = cnt++; 
} 
int pre[MAXN];
bool vis[MAXN];
int st, ed, n, m;
bool BFS (int S, int T) {
    queue<int> q;
    memset(vis, 0, sizeof(vis));
    memset(pre, -1, sizeof(pre));
    q.push(S);  vis[S] = 1;
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(int i = head[u]; i != -1; i = edge[i].nxt) {
            int tmp = edge[i].to;
            if(edge[i].va <= 0 || vis[tmp]) continue;
            pre[tmp] = i; //记录路径
            vis[tmp] = 1;
            if(tmp == T) return 1;
            q.push(tmp);
        }
    }
    return false;
}
int ans;
int EK() {
    int sub;
    while(BFS(st, ed)) {
        sub = 0x3fffff;
        int i = pre[ed];
        while(i != -1) {
            sub = min(sub, edge[i].va);
            i = pre[edge[i].fr];
        }
        i = pre[ed];
        while(i != -1) {
            edge[i].va -= sub; 
            edge[i ^ 1].va += sub;
            i = pre[edge[i].fr];
            /*
            我们要求剩余权值
            而如果每次将边权减去更新部分之后
            求个最小值 即可得到路径上的最小剩余
            反边就对应的加上这个最小剩余
            由于反边和当前边的编号一定相差1,
            所以可以直接^得到
            */
        }
        ans += sub;
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    read(n), read(m), read(st), read(ed);
    int x, y, z;
    memset(head, -1, sizeof head);
    for(int i = 1; i <= m; ++i) {
        read(x), read(y), read(z);
        add_edge(x, y, z);
    }
    cout<<EK()<<endl;
    return 0;
}

其实EK的思路十分简单,就是无数次的BFS直到能够找到我们目标的最大流。
该方法luogu70,除了三个TLE之外都是0ms。该方法非常容易写,足够应付一些数据比较小的题。
考虑一下复杂度,据说是 O(VE2) ,显然不能接受。怎么来的?希腊奶。


Dinic算法

最负盛名的网络流算法,也是最为实用的。
我们先略过最小弧优化,考虑一下朴素的Dinic。

#include <bits/stdc++.h>
using namespace std;
#define MAXE 1000003
struct node{
    int fr, to, va;
    int nxt;
}edge[MAXE];
int head[MAXV], n, m, cnt, st, ed;
inline void read(int &x) {
    x = 0; char c = getchar();
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
inline void add_edge(int u, int v, int w) {
    edge[cnt].fr = u, edge[cnt].to = v, edge[cnt].va = w;
    edge[cnt].nxt = head[u], head[u] = cnt++;
    edge[cnt].fr = v, edge[cnt].to = u, edge[cnt].va = 0;
    edge[cnt].nxt = head[v], head[v] = cnt++;
} 
int deep[MAXV];
bool BFS() {
    memset(deep, 0, sizeof deep);
    queue<int> q;
    q.push(st);
    deep[st] = 1;
    while(!q.empty()) {
        int tmp = q.front();
        q.pop();
        for(int i = head[tmp]; i != -1; i = edge[i].nxt) {
            int v = edge[i].to;
            if( deep[v] || edge[i].va <= 0) continue;
            deep[v] = deep[tmp] + 1;
            q.push(v);
        }
    }
    return deep[ed];
}
int dfs(int u, int flow) { 
    //flow为到达终点最多能增广的值
    if(u == ed) return flow;
    int add = 0; 
    //u点的最大增广量
    for(int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
        int v = edge[i].to;
        if(deep[v] != deep[u] + 1) continue;
        if(!edge[i].va) continue;
        int tmpadd = dfs(v, min(edge[i].va, flow - add));
        edge[i].va -= tmpadd;
        edge[i ^ 1].va += tmpadd;
        add += tmpadd;
    }
    return add;
}
int Dinic() {
    int ans = 0; 
    while(BFS()) 
        ans += dfs(st, 0x3fffff);
    return ans;
}
int main() {
    memset(head, -1, sizeof head);
    scanf("%d%d%d%d", &n, &m, &st, &ed);
    int x, y, z;
    for(int i = 0; i < m; ++i) {
        read(x), read(y), read(z);
        add_edge(x, y, z);
    }
    cout<<Dinic()<<endl;
    return 0;
}

蒟蒻不会手动递归.jpg
考虑一下我们刚才的EK算法,我们首先BFS出了一个可行的最短路,然后以这个最短路为基准转移的。
…求豆麻袋。
为什么我们要增广一次就BFS一次啊,刚才我们在一次BFS中,求出了一条最短路,但是,考虑一棵最短路树,这个最短路只是这棵树一个小小的枝儿。既然如此,何不继续在这个树上搞呢?
首先,我们先BFS出从st到ed的路径距离,然后构造一棵最短路树,然后,我们对这棵最短路树进行DFS操作,最后把得到的结果加起来。完成。


参考资料

https://www.cnblogs.com/smartweed/p/5865727.html
http://www.cnblogs.com/zsboy/archive/2013/01/27/2878810.html

EK算法(网络流,最大流) 一、网络与网络流 给一个有向图(V,E),在V中指定一点,称为源点(记为vs),和另一点,称为汇点(记为vt),其余的点叫做中间点。对于E中每条弧(vi,vj)都对应一个正整数c(vi,vj)&gt;=0(或简写为cij),称为f的容量,则赋权有向图N=(V,E,c,vs,vt)称为一个网络。所谓网络上的流,是指定义在弧集E上的一个函数f=f{f{vi,vj}},并称f(vi,vj)为弧(vi,... 阅读详情

相关推荐

RK3588上rknn_toolkit_lite2报错解决:手把手教你更新librknnrt.so的正确姿势

本文针对在RK3588平台上使用rknn_toolkit_lite2时遇到的“Invalid RKNN model version”等常见错误,提供了完整的诊断与解决方案。文章深入剖析了RKNN生态系统各组件(如librknnrt.so、RKNN Server)版本不兼容的根源,并手把手指导如何安全、正确地更新librknnrt.so运行时库,确保AI模型在RK3588 NPU上实现高效推理。

weixin_29189003的博客 521

最大流的四种常用算法

最大流的四种常用算法 本博客仅用于记录博主自己的代码,只有代码会有注释,若是初学者想进行学习可以移步到最大流 — Edmond Karp算法里面主要讲述了最大流的EK算法,另外的几种算法也有推荐的大佬博客基本可以学会最大流算法。 最大流算法可以说有五种(FF , EK ,Dinic, ISPA, HLPP) 第一种是最暴力的dfs来实现的基本都会有超时的风险,所以不贴出代码 基础模板题:P3376 【模板】网络最大流 进阶毒瘤模板题:P4722 【模板】最大流 加强版 / 预流推进 值得一提的是前四

梅子酒的博客 5392

一分钟学会MATLAB-数据清洗(含完整代码)

数据清洗是数据分析过程中的一个重要步骤,目的是提高数据的质量,以便进行更有效的分析。% 删除超出阈值的行。% 用线性插值填充缺失值。% 删除包含缺失值的行。% 找到缺失值的位置。% 可视化数据,识别异常值。缺失值是数据清洗中常见的问题。通过以上步骤,你可以有效地清洗数据,使其准备好进行后续的分析和建模。

2402_87132195的博客 3316

最大流算法

最大流算法 网络流基础概念 网络流 在一个有向图G=(V,E)G= (V,E)G=(V,E)中: 有一个唯一的源点S(入度为000:出发点) 有一个唯一的汇点T(出度为000:结束点) 图中的每一条边都一个非负的权值,这个权值叫做容量c(u,v)c(u, v)c(u,v) 满足上述条件的图GGG称为网络流图,记为G=(V,E,C)G= (V,E,C)G=(V,E,C) 可以想象成,如果把每条边...

Psychosocial的博客 1万+

【开源教程25】疯壳·开源编队无人机-定高、定点、悬停

【开源教程25】疯壳·开源编队无人机-定高、定点、悬停

efans_Mike的博客 1652

TikTok Shop API密钥获取与PHP实战对接指南

本文详细介绍了TikTok Shop API密钥的获取流程与PHP实战对接方法。从开发者后台创建应用、获取核心的API密钥开始,逐步解析OAuth 2.0授权机制,并提供了完整的PHP封装类示例,涵盖签名生成、API调用、令牌刷新及错误处理,帮助开发者快速实现与TikTok Shop的数据对接与自动化操作。

weixin_29300241的博客 404

最大流算法:Edmond-Karp算法——Ford-Fulkerson算法——Dinic算法

问题定义 给定有向图G=(V,E),其每条边都有容量cv,wcv,wc_{v,w}.这个容量代表这个边可以通过的最大容量。对于任一条边(v,w)(v,w)(v,w),最多有cv,wcv,wc_{v,w}个单位的流可以通过。 图中有两个特殊点,一个是s,称为源点(source),一个是t,称为收点(sink)。 既不是源点也不是收点的点,总的进入的流必须等于总的发出的流。 最大流问题就是确定...

anlian523的博客 1万+

【数据同化第一期】基本概念介绍

【数据同化第一期】基本概念介绍

WW、forever的博客 1904

网络流探索:解决网络最大流问题的算法集锦

网络流探索:解决网络最大流问题的算法集锦

qq_51447436的博客 1万+

YOLOv11涨点改进 | 全网独家创新,注意力改进篇 | TGRS 2025 | 引入APCM自适应像素级协同机制,动态增强目标区域、抑制背景噪声,助力YOLOv11做红外小目标检测有效涨点

本文提出了一种基于APCM模块改进的YOLOv11网络模型,通过像素级局部-全局协同建模增强目标特征并抑制背景噪声。APCM模块采用轻量化设计,无需复杂参数,能有效提升小目标检测性能。文章详细介绍了APCM的原理、优势及其在红外小目标检测中的应用,包括模块结构、核心代码实现和YAML配置文件修改方法。实验结果表明,该方法在NUAA-SIRST和IRSTD-1K数据集上优于现有技术,显著提高了复杂场景下的检测精度与鲁棒性。

Ai缝合怪、助力小伙伴高效发论文 118

9、自动定理证明的发展历程与关键技术

本文全面介绍了自动定理证明的发展历程、关键技术及其实际应用,包括消解原理、参数化、支撑集策略等核心方法,并探讨了算法优化、数据结构优化及并行计算等提升效率的手段。同时,文章展望了未来发展方向,如深度学习在定理证明中的应用、交互式定理证明以及高阶逻辑的研究前景。

ll5678的博客 507

【算法导论】最大流算法

最大流问题就是在容量容许的条件下,从源点到汇点所能通过的最大流量。 1 流网络 网络流G=(v, E)是一个有向图,其中每条边(u, v)均有一个非负的容量值,记为c(u, v) ≧ 0。如果(u, v) ∉ E则可以规定c(u, v) = 0。网络流中有两个特殊的顶点,即源点s和汇点t。 与网络流相关的一个概念是流。设G是一个流网络,其容量为c。设s为网络的源点,t为汇点,那么G的流是一个

青峰碧陋室 1万+

【实战】YOLOv5/v8模型→RK3588 NPU高效部署:模型转换/量化/精度调优完整指南​

摘要: 本教程详细介绍了YOLOv5模型在RK3588 NPU上的优化部署流程,重点解析了架构转换与量化技术。通过将检测头输出结构与decode操作分离,显著提升了模型在NPU上的兼容性和计算效率。LetterBox预处理方案有效保持图像宽高比,相比直接resize提升检测精度。INT8量化技术采用非对称量化策略,通过scale和zero_point参数实现浮点到整数的转换,在保证精度的同时大幅提升推理速度。实验表明,优化后的模型在RK3588上实现了高效的实时目标检测性能,为边缘AI部署提供了完整解决方案

LXY_LOVE36的博客 625

网络流 最大流SAPkuangbin模板

hdu 1532 求1~n的最大流 #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int MAXN = 210; //点数的最大值 const int MAXM...

baichuan9723的博客 110

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

网络流黑科技

太无聊了就来写博客吧。 想起了很久以前看到的网络流黑科技。 可以优化dinic复杂度,虽然还是过不了loj上那个毒瘤网络流,但是可以拿88分。 大致就是先确定最大流的上界,设为x 再从高到低枚举二的幂,只跑残量网络上大于该幂的边,计入流量。 好像可以优化复杂度。 loj127 88分代码 #pragma GCC optimize(3) #pragma GCC target("a...

weixin_30279671的博客 146

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

网络流之SAP算法

在SAP算法中,我们定义每个顶点的距离标号(Distance Labels),即残留网络中这个点到汇点的距离。然后,我们只在距离标号相邻的点间寻找增广路径。如果从一个点出发没有容许边,就对重标记并回溯(类似预流推进)。首先介绍一些定义: 残留容量:容量-流量。即,残留容量r[i,j]=c[i,j]-f[i,j]。如果只求流值,则在网络流算法中只需记录残量,而不必记录容量和流量。 残留边

Alone_L的专栏 967

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

有源汇上下界最大流

更好的阅读体验:这里 传送门:这里 分析 这是一道有源汇上下界最大流的模板题(废话)。 既然是网络流的问题,故应该先将图建出来: 根据题目特征, 我们将少女和每一天看作是图中的点。 当然,因为每一天都有拍照次数的限制,我们可以加一个源点 sss ,向每一天连边,这个边的容量范围是 [0,Di][0,D_i][0,Di​] 。 类似地,因为每个少女都有一个至少拍照张数的限定,所以加一个汇点 ttt ,然后让每个少女向汇点连边,容量范围自然是 [Gi,∞][G_i,∞][Gi​,∞] 。 至于少

melon_sama的博客 275

zoj 3792 最小割等于最大流 Romantic Value

可以把残留网络的零流的边设成容量为1,其他设成无穷,再求一次最大流。最后流量一定等于割边边数 另外: 还有一种求割边的办法。 因为每次我们求出来最大流都是割边的流量,那么,我们可以把原先边的容量×10000+1,那么求出来的最大流/10000不会影响原先的答案,而最大流%10000则是割边的数目

u013087645的专栏 852

全面理解网络流中的最大流问题

网络流(最大流问题) 前序 在将网络里实现算法之前,我们得聊聊网络流究竟是个什么东西,毕竟只有知道它的样貌,才能继续看懂下面的定义,对吧? 首先,网络流不仅仅指的是什么FF算法、dinic算法。算法只是用来解决问题的(稍后我们会更加能体会这一点),而网络流,指的就是这一系列存在图论中的,关于“流(Flow)”的问题。 参考:Network flow problem - Wikipedia 网络流中有以下几种问题: 最大流问题 最小费用流问题 多商品流问题(multi-commodity flow p

Nopoduct的博客 1万+

网络流之最大流算法(EdmondsKarp)

求网络流有很多算法,这几天学习了两种,记录一下EK算法。 首先是网络流中的一些定义: V表示整个图中的所有结点的集合. E表示整个图中所有边的集合. G = (V,E) ,表示整个图. s表示网络的源点,t表示网络的汇点. 对于每条边(u,v),有一个容量c(u,v)   (c(u,v)>=0),如果c(u,v)=0,则表示(u,v)不存在在网络中。相反,如果原网络中不存在边(u,v)

大神养成中..... 9万+

网络流之最大流算法总结(FF, EK, Dinic)

目录 FF算法:最基础的最大流算法 EK算法:每次BFS寻找増广路 Dinic算法:EK算法的优化 Dinic+链式前向星 这里以POJ1273这道题为例,题目链接:http://poj.org/problem?id=1273 FF算法:最基础的最大流算法 通过DFS増广,直到不能増广为止。 记最大流的流量为F,FF算法最多进行F次DFS,所以其复杂度为O(F|E|),每一次DFS...

7116

网络流——最大流

一、什么是网络流 网络流是指给定一个有向图,其中有两个特殊的点:源点sss(Source)和汇点ttt(Sink);每条边都有一个指定的流量上限,下文均称之为容量(Capacity),即经过这条边的流量不能超过容量,这样的图被称为网络流图。同时,除了源点和汇点外,所有点的入流和出流都相等,源点只有流出的流,汇点只有流入的流,网络流就是从 sss 到 ttt 的一个可行流。 二、可行流、最大流 定义...

Wlis的博客 5465

网络流 最大流 最小割 费用流

【腾讯文档】网络流初步 网络流初步 文章目录网络流初步一、网络流简介1. 网络2. 流3. 再次理解网络流二、常见题型(三种)三、相关问题对应算法介绍1.最大流(1) FF算法 - Ford-Fulkerson算法(2)EK算法 - Edmonds-Karp增广路算法(3)Dinic算法(4)ISAP算法总结2.最小割最大流最小割定理割(CUT)3.费用流 问题: 一、网络流简介 网络流是算法竞赛中的一个重要的模型,它有两个部分:网络和流。 图片来源 1. 网络 网络就是一张有向图 G = (V,E)。

SZTU_ZJB的博客 3163

网络流的最大流入门(从普通算法到dinic优化)

网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。网络流的理论和应用在不断发展。而我们今天要讲的就是网络流里的一种常见问题——最大流问题。 最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。求最大流的标号算法最早由福特和福克逊与与1956年提出,20世纪50年代福

stevensonson的博客 1万+

网络流(最大流)

网络流的相关定义: 源点:有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点。 汇点:另一个点也很特殊,只进不出,叫做汇点。 容量和流量:每条有向边上有两个量,容量和流量,从i到j的容量通常用c[i,j]表示,流量则通常是f[i,j]. 通常可以把这些边想象成道路,流量就是这条道路的车流量,容量就是道路可承受的最大的车流量。很显然的,流量<=容量。而对于每个不是源点和汇点的点...

weixin_42165786的博客 1万+

图算法-网络流的最大流问题

首先认识网络流(network-flows),它是一种类比水流的解决问题方法,与线性规划密切相关。网络流的应用已遍及通讯、运输、电力、工程规划、任务分派、设备更新以及计算机辅助设计等众多领域。最大流问题(maximum flow problem)是网络流图里面一种常见问题,它是一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。

linkedin_21843693的博客 1378
上一篇: 网络流 (一) 最大流的原理图解
下一篇: 网络流(三) 最小割 平面图转对偶图
LittleRewriter
博客等级 码龄9年 35粉丝 60原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值