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

网络流——最大流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,... 阅读详情

相关推荐

【信创-k8s】银河麒麟V10国防版+鲲鹏/飞腾(arm64架构)在线/离线部署k8s1.30+kubesphere

银河麒麟作为国家核高基专项的重要成果,国防版凭借其卓越的安全性和可靠性,已成为军工领域的首选操作系统。之前我们在适配麒麟V4国防版的过程中已发现诸多安全性要求,而麒麟V10国防版在安全防护等级上又达到了更高的级别。本文将主要演示离线部署,因为军工项目基本不会出现联网场景。即使在线,也可以按离线方式部署,且离线部署由于有私有仓库,不会存在镜像获取不到和丢失情况。

jiaworld的博客 730

最大流的四种常用算法

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

梅子酒的博客 5392

信息抽取实战:三元组抽取(限定领域 vs 开放领域)(附代码)

信息抽取实战:三元组抽取 目录信息抽取实战:三元组抽取一、限定领域的三元组抽取比赛介绍数据分析序列标注模型关系分类模型三元组提取总结开放领域的三元组抽取标注平台文本分类新数据进行三元组抽取总结参考文献 一、限定领域的三元组抽取   本项目将会介绍在2019语言与智能技术竞赛的三元组抽取比赛方面的一次尝试。由于该比赛早已结束,当时也没有参加这个比赛,因此没有测评成绩,我们也只能拿到训练集和验证集。但是,这并不耽误我们在这方面做实验。 比赛介绍   该比赛的网址为:http://lic2019.ccf.org.

南有芙蕖 2万+

最大流算法

最大流算法 网络流基础概念 网络流 在一个有向图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万+

MATLAB实战:利用扫频数据重构系统伯德图的关键步骤

本文详细介绍了如何利用MATLAB处理扫频数据并重构系统伯德图的完整实战流程。内容涵盖数据导入与清洗、增益与相位的精确计算、频率响应数据对象(frd)的构建、数据平滑与插值处理,以及最终生成专业伯德图并进行关键参数(如相位裕度)标注的方法。文章重点解决了从实测“黑盒子”系统数据出发,获取直观频率响应特性曲线的核心问题,为控制系统分析与设计提供了实用指南。

weixin_29098117的博客 398

EFR32无线SoC开发指南:从环境搭建到性能优化

物联网边缘设备开发中,无线SoC芯片的选择与开发环境配置是关键第一步。EFR32作为Silicon Labs推出的多协议无线SoC系列,配合Simplicity Studio IDE,为开发者提供了完整的解决方案。本文以EFR32xG22开发套件为例,详细介绍开发环境搭建、工程创建、硬件配置等核心环节,特别针对RAILtest示例工程进行深入解析。通过实际案例演示如何配置无线参数、优化低功耗模式,并分享串口终端交互、吞吐量测试等实战技巧。对于开发者常见的问题如设备识别失败、无线通信异常等,提供了系统化的排查

weixin_30342363的博客 353

最大流算法: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万+

智能化运维(AIOps)

• 调查显示,54.79%的企业当前着重关注智能运维的质量领域(包括异常检测、告警收敛、根因分析、 故障处置等)能力建设,其次45.77%的企业关注效率领域,45.49%的企业关注成本领域,30.82%的 企业关注安全领域。从目前的发展情况来看,现阶段AIOps能力大多集中在L2级别, 主要以系统辅助分析,帮助人工进行决策和操作为主,较为领先的 能力实践可以达到L3级别,而L4和L5级别随着AIOps的技术发展 和能力的逐步增强,将是未来智能运维能力建设的发展方向和目标。

追求更专业的设计 3105

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

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

qq_51447436的博客 1万+

BAQ压缩原理

BAQ——Block Adaptive Quantization,块自适应量化,一种数据压缩算法。

2875

Buck电源设计常见的一些问题(五)MOS管振荡抑制方法(三)

关于开关节点振荡的产生机制和抑制问题,总结了三种抑制方法。第一种方法是利用输入端的高频去耦电容;第二种方法是设计 RC 缓冲电路;第三种方法是优化自举电路的串联电阻。以上三种方法均通过实验加以验证,对开关节点振荡具有很好的抑制作用。应该综合同步 Buck 变换器的各项指标权衡设计。

小幽余生不加糖 1633

【算法导论】最大流算法

最大流问题就是在容量容许的条件下,从源点到汇点所能通过的最大流量。 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万+

【AI智能体】Codex 高级进阶使用技巧项目实战操作详解

Codex 高级进阶使用技巧项目实战操作详解

congge 1万+

网络流 最大流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

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

网络流黑科技

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

weixin_30279671的博客 146

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

网络流之SAP算法

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

Alone_L的专栏 967

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

有源汇上下界最大流

更好的阅读体验:这里 传送门:这里 分析 这是一道有源汇上下界最大流的模板题(废话)。 既然是网络流的问题,故应该先将图建出来: 根据题目特征, 我们将少女和每一天看作是图中的点。 当然,因为每一天都有拍照次数的限制,我们可以加一个源点 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、付费专栏及课程。

余额充值