Dinic+当前弧优化

【坤坤讲师--图】Dinic 比如我们找到了一条增广路径,这条增广路径所增加的流量为 C,则这条增广路径上必然有一条边残余容量为 C,这是我们不必又从起点开始寻找增广路,而是从 i 顶点出发找增广路,这样就减少了重复计算,提高了效率,这好像就是所说的多路增广。首先我们得知道,Dinic的基本算法步骤是,先算出剩余图,然后用剩余图算层次图,然后在层次图里找增广路。不知道你想到没有,这个层次图找增广路的方法,恰恰就是Ford-Fulkerson类算法的时间耗费最大的地方,就是找一个最短的增广路。层次图是什么东西呢。 阅读详情

  Dinic算法是不停用BFS构造层次图,然后用阻塞流增广。

  什么叫层次图呢》假设在残量网络中,起点到结点u的距离为dist(u),那么这个dist(u)看作结点u的层次,只保留每个点出发到下一个层次的弧,得到的图就是层次图。阻塞流是不考虑反向弧时的极大流。最多计算N-1次阻塞流(因为每次沿阻塞流增广后,t相对于s的层次至少增加1),每次阻塞流的计算时间不超过O(MN),因此总时间复杂度为O(N^2M),但实际上比这个快。

  当前弧优化是什么意思呢?注意在DFS中用cur[x]表示当前应该从x的编号为cur[x]的边开始访问,也就是说从0到cur[x]-1的这些边都不用再访问了,相当于删掉了,达到了满流。DFS(x,a)表示当前在x节点,有流量a,到终点t的最大流。当前弧优化在DFS里的关键点在if(a==0) break;也就是说对于结点x,如果x连接的前面一些弧已经能把a这么多的流量都送到终点,就不需要再去访问后面的一些弧了,当前未满的弧和后面未访问的弧等到下次再访问结点x的时候再去增广。

struct Edge{
    int from,to,cap,flow;
};

struct Dinic{
    int n,m,s,t;            //结点数,边数(包括反向弧),源点编号和汇点编号
    vector<Edge> edges;     //边表。edge[e]和edge[e^1]互为反向弧
    vector<int> G[MAXN];    //邻接表,G[i][j]表示节点i和第j条边在e数组中的序号
    bool vis[MAXN];         //BFS使用
    int d[MAXN];            //从起点到i的距离
    int cur[MAXN];          //当前弧下标

    void clear_all(int n){
        for(int i=0;i<n;i++) G[i].clear();
        edges.clear();
    }
    void clear_flow(){
        int len=edges.size();
        for(int i=0;i<len;i++) edges[i].flow=0;
    }
    void add_edge(int from,int to,int cap){
        edges.push_back((Edge){from,to,cap,0});
        edges.push_back((Edge){to,from,0,0});
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    bool BFS(){
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!q.empty()){
            int x=q.front();
            q.pop();
            int len=G[x].size();
            for(int i=0;i<len;i++){
                Edge& e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow){
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    int DFS(int x,int a){
        if(x==t||a==0) return a;
        int flow=0,f,len=G[x].size();
        for(int& i=cur[x];i<len;i++){
            Edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }
    int maxflow(int s,int t){
        this->s=s;
        this->t=t;
        int flow=0;
        while(BFS()){
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,INF);
        }
        return flow;
    }
    vector<int> mincut(){   //call this after maxflow
        vector<int> ans;
        int len=edges.size();
        for(int i=0;i<len;i++){
            Edge& e=edges[i];
            if(vis[e.from]&&!vis[e.to]&&e.cap>0) ans.push_back(i);
        }
        return ans;
    }
    void reduce(){
        int len=edges.size();
        for(int i=0;i<len;i++) edges[i].cap-=edges[i].flow;
    }
};


最大流DInic算法(链式前向星) 给师弟师妹们讲网络流Dinic算法与可行流用到的讲义,感觉还是不错,分享一下~ 立即下载

相关推荐

ARTIX-7 GTP 3G-SDI 工程构建与调试实战

本文详细介绍了基于ARTIX-7 FPGA和GTP收发器的3G-SDI工程构建与调试实战。从基础概念解析到Vivado工程创建、GTP IP核配置、SDI IP核集成,再到系统集成与时钟域处理,提供了全面的技术指导。文章还分享了调试技巧、常见问题排查方法以及性能验证步骤,帮助开发者快速掌握3G-SDI视频传输技术的实现与优化。

weixin_30443813的博客 256

Dinic & 当前弧优化

Dinic的核心思想就是先跑一遍Bfs BfsBfs,为每个位置设置一个高度,一个点的高度为前一个点+1 +1+1(如果某一条边已经满流则不设置) 为什么非得要用bfs建立分层图 解释: 虽然说我们已经知道了增广路的实现,但是单纯地这样选择可能会陷入不好的境地,比如说这个经典的例子: 我们一眼可以看出最大流是999(s->v-&g...

mlm5678的博客 1608

Wireshark时间分析实战:精准调试网络延迟与时间同步问题

本文深入探讨了Wireshark在网络延迟与时间同步问题分析中的核心应用。通过实战案例,详细讲解了如何设置时间显示格式、利用时间参考点量化关键路径延迟,以及运用时间平移功能校正错位时间轴。掌握这些时间分析技巧,能帮助网络工程师精准定位隐藏于数据包时序中的性能瓶颈与故障根源。

weixin_29290963的博客 261

关于dinic算法中当前弧如何优化问题

刚开始学最大流dinic算法时,并没有运用优化,但是也解决了一些题。后来在做hdu的3572时,一直超时,被卡时间。所以上网查了下,了解到dinic中必须要加当前弧优化才可以过。然后查了下当前弧优化是什么鬼,网上的解释也是比较模糊,自己便思考了一番,于是说一下自己的想法。当前弧优化就是为了防止走重复的边,从而较少了时间。int dfs(int k,int y) { if(k==maxl+1...

zyy.cpp 的博客 1251

Python 音频: sounddevice 使用 左声道/右声道/立体声 --- 播放,录音

# coding: utf8 """ Python 音频: 使用 sounddevice 操作声卡的 左声道, 右声道, 立体声 仅限 MME, Windows DirectSound, Windows WASAPI, Windows WDM-KS 等支持双声道的驱动类型 """ import os import sounddevice as sd import soundfile mapping_left_ch = 1 # 左声道为 1 mapping_right_ch

weixin_42019925的博客 4926

[模板] - 网络流 - Dinic & 当前弧优化

函数:邻接表部分:const int INF = 0x3f3f3f3f, maxn = 157; int N, NP, NC, M; struct E { int u, v, flow; E(int u = 0, int v = 0, int flow = 0): u(u), v(v), flow(flow) {} } edg[maxn * maxn];int cnt_edg, S,

LucienShui 4168

指纹对抗指南:如何绕过Cloudflare与Akamai的5s盾与浏览器指纹检测

现在的CDN反爬技术虽然越来越强,但是道高一尺魔高一丈,只要掌握了指纹伪造、流量伪装、行为模拟这些核心技术,就可以绕过绝大多数的防护措施。对抗过程中要注意效率和成本的平衡,小规模爬取用Playwright+stealth最方便,大规模爬取用curl_cffi+代理池性价比最高,遇到验证码用打码平台或者自动识别服务,不需要死磕破解。本文介绍的方案已经在实战中验证过,可以绕过95%以上的Cloudflare/Akamai防护,成功率非常高。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 295

最大流与最小割

   注:本人只是一个萌新,有一些地方的用语会不太专业(大佬:是十分不专业),我不会用什么技术用语,这些文章对那些跟我一样的萌新会比较适用!   最大流:       原题地址   最大流我讲的是我自己对dinic算法的一些思想,希望对你会有用!   我记网络流靠三个关键字:       1.找最短路径   将流量流向终点,且损害最少的边,这是找路径的一个关键,那么,便可以把分出最少...

蒟蒻QMQ 585

【乐企-工具篇】生成发票左上角二维码

【代码】【乐企-业务篇】生成发票左上角二维码。

九七的博客 707

【机器学习】随机森林(Random Forest,简称 RF):预测光伏电站功率 || 缺失数据处理 || 重复行处理...

【机器学习】随机森林(Random Forest,简称 RF):预测光伏电站功率。

追光者♂:记录、分享、总结、提升,现象级专栏《Python从入门到人工智能》作者,无惧黑暗,坚信曙光 1647

最大流 dinic算法的优化(当前弧优化)思路+代码模板

Dinic算法 普通的dinic算法在有些时候会被卡掉,因为每次dfs太多了,所以对此就有了当前弧优化来解决这个问题。 什么是当前弧优化 当前弧优化就是说我们在每次dfs找的时候,把已经榨干的点删掉,我们直接从可以增加流量的边开始。 假设我们的残留网络已经更新成现在这个网络了,假设源点s出发的有编号1、2、3号边,1和2号边都无法再增加流量了,没有用了(相当于这两条边被榨干了),那么我们在下次bfs得到的分层图再dfs找增广路时,就不考虑1和2号边了,直接从s出发去3号边找。就能省略很多层递归。 当前弧优

harry12138小白的博客 3253

(十二)深入理解蓝牙BLE之“移植Bluez 5.18源码到嵌入式平台”

在某嵌入式平台进行蓝牙开发,发现上面居然没有btmon,hciattach,hcitool等蓝牙调试工具,无奈之下,只好移植bluez协议栈到目标嵌入式平台,建议移植5.18版本(最新的5.54版本居然hcitool等工具不是默认编译的,需要修改Makefile才可以)。 看到很多讲解移植过程的文章都是需要积分的,觉得写一篇免积分的文章还是有些意义的,欢迎同行来交流。 移植环境:Linux ubuntu 目标平台:sigmastar 星宸科技 配置交叉编译工具链:export PATH=$PATH:

2964

最大流算法——Dinic & 当前弧优化

洛谷博客地址:-&amp;gt;Click Here&amp;lt;-,求捧场 不会写EKEKEK的蒟蒻【我】哭出了声 所以来讲讲DinicDinicDinic好了…… DinicDinicDinic的核心思想就是先跑一遍BfsBfsBfs,为每个位置设置一个高度,一个点的高度为前一个点+1+1+1(如果某一条边已经满流则不设置) 在解释为什么要给图上的点设置高度,即设置所谓的分层图之前,我们先来讲讲网络流的建...

Venus的博客 1487

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)

//非当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cstring> #include <queue> #define INF 0x3f3f3f3f using namespace std; int tab[250][250];//邻接矩...

日拱一卒,功不唐捐 2876

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

POJ 1273 (Dinic模板 + 当前弧优化)

昨天晚上看明白,今天下午把板子打出来 Dinic简单概括就是 1,利用bfs寻路分层,保证每一次只能从第x层走到第x+1层,省去了很多冗余时间 2,利用dfs递归更新增广路径,如果找不到继续执行步骤1 3,如果步骤1无法分层成功,证明不存在从源点到汇点的一条可行路径,退出程序 当前弧优化: 在此基础上加上当前弧优化,即如果此次dfs进行到点i的时候无法继续搜索,我们下次bfs重新分层后...

STOP 419

Dinic算法当前弧优化:原理、实现与性能提升详解

在网络流算法中,最大流问题是核心基础,其求解效率直接影响图论与组合优化任务的性能。Dinic算法通过分层图与多路增广,在理论上达到了较高的时间复杂度,但朴素实现存在严重的重复遍历瓶颈。当前弧优化正是针对这一瓶颈的关键工程技巧,它通过为每个节点维护一个“当前弧”指针,记录下一次DFS应尝试的起始边,利用引用传递机制,在同一轮分层图内确保每条边仅被有效访问一次,从而避免了大量无效遍历。这一优化将算法从理论高效转化为实际高效,尤其适用于边数稠密或存在特定结构的网络流问题。理解当前弧优化与DFS多路增广的协同机制,

weixin_30430169的博客 5824

Island Transport 【HDU - 4280】【最大流Dinic+当前弧优化】

题目链接 先给大家讲一下什么是当前弧优化,就是一个节点从后往前去减的时候,我们很多时候通过dfs()的方式已经榨干了这条路,但是如果下一次我们还是要从它开始寻的话岂不是去浪费时间,不如去记录下来我们压榨到了第几条边了,这样子会好得多了,至少从TLE变成了G++卡过去的AC了。 这道题本身是没有什么难度的建边的,但是却存在卡时间这样的操作,所以,我们是需要做出一些优化来操作的。——当前弧...

既然弱小,就只顾变强就是了 260

Dinic + 当前弧优化 教程及模板

在阅读本文前,建议先自学最大流的Ek算法。 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广。换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低。于是我们可以考虑优化。 核心思路 在一次BFS中,找到的增广路可能不止一条,这时我们可以本着“尽量少进行BFS”的想法,在一次bfs后把所有能增广的路径全部增广。 具体怎么做呢? 仍然是: while(bfs(...

单精度的梦 3214

Dinic当前弧优化 模板及教程

在阅读本文前,建议先自学最大流的Ek算法。 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广。换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低。于是我们可以考虑优化。 核心思路 在一次BFS中,找到的增广路可能不止一条,这时我们可以本着“尽量少进行BFS”的想法,在一次bfs后把所有能增广的路径全部增广。具体怎么做呢?仍然是:while(bfs(源点,汇点)) ...

weixin_30569153的博客 119

Dinic算法性能提升关键:当前弧优化原理与实现详解

在网络流算法中,Dinic算法因其分层图和多路增广的设计,成为求解最大流问题的常用方法。其核心原理是通过BFS构建层级网络,再通过DFS在层级限制下寻找增广路径,从而高效地推送流量。然而,在稠密图或大规模数据下,算法的常数因子可能成为性能瓶颈。当前弧优化正是针对这一瓶颈的关键技术,它通过为每个节点维护一个指针,记录DFS搜索进度,避免重复检查已失效的边,将每条边的检查次数降至常数级别,从而大幅提升实际运行效率。该优化在工程实践中至关重要,能帮助算法应对边数达10^5级别的大规模网络流问题,是竞赛和实际应用中

weixin_34203832的博客 391

P3376 网络流-最大流模板题(Dinic+当前弧优化)

(点击此处查看原题) Dinic算法 Dinic算法相对于EK算法,主要区别在于Dinic算法对图实现了分层,使得我们可以用一次bfs,一次dfs使得多条增广路得到增广 普通的Dinic算法已经可以处理绝大多数最大流(最小割)的题目了,但是总是有些题目会卡住普通的Dinic算法,此时我们就需要用到当前弧优化了 当前弧优化简述 不要小看当前弧优化,这个优化效果可是很明显的,就这个...

weixin_30497527的博客 188

Dinic算法+多路增广+当前弧优化+爆点

Dinic算法是最大流算法中比较常用的,效率也很高。 普通的Dinic,在原来的求增广路线的基础上添加了一个bfs(),用来分层,分层可以使用一个数组标记节点所在的层数,搜索增广路线时,严格按照节点层数递增的顺序搜索,这样可使得dfs()的深度最低,从而节省时间。 当前弧优化:例如 中间节点A,有三个流向,A->B, A->C,A->D,在A点时, 如果A->B,A-...

AYZXX的博客 1095

P3376 网络最大流模板(Dinic + dfs多路增广优化 + 炸点优化 + 当前弧优化)

### P3376题目链接 ### 这里讲一下三种优化的实现以及正确性。 1、dfs多路增广优化 一般的Dinic算法中是这样的,bfs()用于标记多条增广路,以至于能一次 bfs()出多次dfs()增广路。那么就会有 while(bfs())一次,然后 dfs()n 次,出n条增广路。 那么我们 dfs 的优化在于使得一次dfs()直接累加出这一次b...

diefen9380的博客 600

洛谷 P1361 小M的作物 最小割 网络流 Dinic+当前弧优化 同类则额外奖励

题目链接: https://www.luogu.com.cn/problem/P1361 第一遍做了4个小时不理解,没有做出来,可以参考题解区这个博客: https://www.luogu.com.cn/blog/ButterflyDew/solution-p1361 几天后做了它的升级版,回头做这个10min ac: https://blog.youkuaiyun.com/aiwo13763016...

aiwo1376301646的博客 264
上一篇: hdu5044 Tree 上海网络赛1003 LCA+输入输出外挂
下一篇: uva1324 - Bring Them There 网络流
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值