图论--最大流 Dinic_weixin_30399821的博客-程序员宅基地

最大流:源点到汇点的流量最大

Dinic基本思想:

  1. bfs广搜实现查找多条增广路(可能可以增加流量的路),构建一张层次图。
  2. 在bfs找到增广路的前提下多次dfs深搜进行增广直至所有已查找到的增广路用完

优化:当前弧优化:

  在每次更新完的层次图中(即每一次bfs完后),dfs每增广完一条路之后,该路的价值就已可以看作用尽了,没有必要在之后的dfs中再次深搜该路。故记录下用完价值的边的下一条边,下一次的dfs直接从该边开始,这样就避免了不必要的增广。

/*
普通图的情况下:复杂度O(V2 E)
二分图下的复杂度:O(根号(VE))
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxv = 10004, maxe = 200004;
/*cap 为边的容量 */
struct Edge {
    int next, to, cap;
}e[maxe];
int head[maxv], cnte = 1;
int level[maxv], cur[maxv];
int n, m;

inline bool min(const int& a, const int& b) { return a<b? a:b; }

inline void add_edge(int from, int to, int cap) {
    cnte += 1;
    e[cnte].next = head[from], e[cnte].to = to, e[cnte].cap = cap;
    head[from] = cnte;

    //反向边, 初始的容量为0
    cnte += 1;
    e[cnte].next = head[to], e[cnte].to = from, e[cnte].cap = 0;
    head[to] = cnte;
    return;
}

//bfs分层找增广路,建立层次图
bool bfs(int s, int t) {
    memset(level, 0, sizeof(level));
    queue<int> q;    while(q.size()) q.pop();
    level[s] = 1;
    q.push(s);
    while(q.size())
    {
        int now = q.front(); q.pop();
        for(int i=head[now]; i; i=e[i].next)
        {
            //有容量且没有被标记
            if(level[e[i].to]==0 && e[i].cap > 0) {
                level[e[i].to] = level[now]+1;
                q.push(e[i].to);
            }
        }
    }

    //终点的level大于0说明存在增广路
    return level[t] > 0;
}

//增广流量
//in 为源点输入到这个点上的最小边权
//now 收到的支持,不一定真正能够用到
//@return 真正的输出流量
/** dfs的意义为到达now时传进的最大流量 */
int dfs(int now, int t, int in) {
    if(!in || now==t)
        return in;

    //i为cur[now]的引用-->cur[now]随着i改变
    for(int& i=cur[now]; i; i=e[i].next) {
        int nv = e[i].to;
        if(level[nv]==level[now]+1 && e[i].cap>0)
        {
            // out为点now经边i流向nv的流量
            int out = dfs(nv, t, min(in, e[i].cap)); //一路上都受到最小流量的限制
            if(out > 0) {
                e[i].cap -= out;
                e[i^1].cap += out; //反向边,用于反悔
                return out;
            }
        }
    }
    return 0; //没有增广路,返回0
}

//注意是两个while,每次bfs找到多个增广路后
//多次dfs计算网络中所有增广路的流量
int dinic(int s, int t) {
    int max_flow = 0;
    while(bfs(s, t))
    {
        //每次建立完层次图之后记录当前弧
        for(int i=1; i<=n; ++i)
            cur[i] = head[i];
        int tmp=0;
        while(tmp = dfs(s, t, 0x3f3f3f3f))
            max_flow += tmp;
    }
    return max_flow;
}

 

转载于:https://www.cnblogs.com/GorgeousBankarian/p/11409685.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30399821/article/details/102030163

智能推荐

程序员的十个等级_程序员十级是什么概念-程序员宅基地

自西方文艺复兴以来,中国在自然科学方面落后西方很多,软件领域也不例外。当然现在中国的许多程序员们对此可能有许多不同的意见,有些人认为中国的程序员水平远落后于西方,有些则认为中国的程序员个人能力并不比西方的程序员差,只是整个软件产业落后而已。那么,到底中国的程序员水平比西方程序员水平差,还是中国有许多优秀的程序员达到或超过了西方程序员同等水平呢?要解决这个问题,必须先知道程序员有多少种技术层级,..._程序员十级是什么概念

Lessons on development of 64-bit C/C++ applications(64位C/C++开发教程)-程序员宅基地

http://www.viva64.com/en/l/ Lesson 01. What 64-bit systems are.Lesson 02. Support of 32-bit applications.Lesson 03. Porting code to 64-bit systems. The pros and cons.Lesson 04. Creating the 64-b

Linux实战之MySQL数据库——基于MHA的Mysql集群架构_linux mysql基于mha的高可用架构-程序员宅基地

MySQL MHA架构介绍MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程..._linux mysql基于mha的高可用架构

根据pom文件指定依赖在本地repository复制到新建文件夹_pom 指定repository-程序员宅基地

xl_echo编辑整理,欢迎转载,转载请声明文章来源。更多IT、编程案例、资料请联系QQ:1280023003百战不败,依不自称常胜,百败不颓,依能奋力前行。——这才是真正的堪称强大!!该功能的实现主要是便于maven项目或者web的jar引入,能够快速通过pom文件找到需要的jar包。指定要输出的路径之后,该功能会直接通过pom文件寻找repository,并复制。最终导入项目就不需要一个..._pom 指定repository

sql-labs通关记录(7-10)_you are in.... use outfile......-程序员宅基地

less-7先测试单引号,会报错。发现,报错信息没有像之前一样,输出一些有用的信息/对id参数(闭合语句的条件)进行一波测试从以上两条信息可以推断出,单引号是闭合语句的条件之一接着带着单引号进行测试。单引号加括号:index.php?id=1’)%23单引号加两个括号:index.php?id=1’))%23ok,这里我们测试出了正确的闭合语句,可以推断后端查询语句为:sel..._you are in.... use outfile......

vivado生成ltx文件命令_Vivado生成及使用edf文件-程序员宅基地

前言EDF文件可以直接导入Vivado,而无需Verilog源文件。好处:(1) 避免沙雕队友修改源代码,则可以直接提交EDF网表文件。(2) 避免用户剽窃劳动成果。(3) 对于无需更改的设计复用,直接用EDF网表会贼方便。软件版本:Vivado2018.3流程生成EDF网表文件(1)设置需提交的源代码的最顶层为TOP层。可以看到内部调用了2个IP块。(2)在设置选项的综合设置中..._vivado如何生成ltx文件

随便推点

L1-010 比较大小 (10分)-程序员宅基地

L1-010比较大小(10分)本题要求将输入的任意3个整数从小到大输出。输入格式:输入在一行中给出3个整数,其间以空格分隔。输出格式:在一行中将3个整数从小到大输出,其间以“->”相连。输入样例:4 2 8输出样例:2->4->8#include<iostream>#include<algorithm&...

Spring Cloud Alibaba Nacos Config原理分析_豆浆蛋饼的博客-程序员宅基地

前言Nacos Spring Cloud的使用方法与Nacos Spring Boot的使用方法类似,都是通过添加依赖与在配置文件中增加配置来完成接入。需要注意的是在Spring Cloud应用中必须要配置spring.application.name,因为它是构成 Nacos 配置管理dataId字段的一部分,在Nacos Spring Cloud中配置文件的dataId完整格式为prefix-spring.profiles.active.file-extension,当然Nacos Spring Cl

小白玩Ubuntu——一脸懵逼到爱不释手-程序员宅基地

为什么80%的码农都做不了架构师?>>> ..._mac unable to run mksdcard sdk tool

Mybatis快速上手5 模糊查询和动态SQL_mybatis 动态查询-程序员宅基地

Mybatis快速上手5 模糊查询和动态SQL环境 :Eclipse+Tomcat9+JDK10+Mybatis-3.1.1、Navicat需求代码建库,建表config.xmluserMapper.xmlConditionUser.javaJTest5.java其它结果环境 :Eclipse+Tomcat9+JDK10+Mybatis-3.1.1、Navicattest1~8分别对应八章,本章使用包test5、tool,文件config.xml、db.properties、log4j.propert_mybatis 动态查询

hdu 1534 Schedule Problem(差分约束求最长路)-程序员宅基地

Schedule ProblemTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 940 Accepted Submission(s): 368Special JudgeProblem Description