图论--网络流最大流问题
问题表述:给定一幅图(n个结点,m条边),每一条边有一个容量,现在需要将一些物品从结点s(称为源点)运送到结点t(称为汇点),可以从其他结点中转,求最大的运送量。
在介绍最大流问题的解决方法之前,先介绍几个概念.
网络:网络是一个有向带权图,包含一个源点和一个汇点,没有反向平行边。
网络流:网络流即网上的流,是定义在网络边集E上的一个非负函数flow={flow(u,v)}, flow(u,v)是边上的流量。
可行流:满足以下两个性质的网络流flow称为可行流。
容量约束:每条边的实际流量不能超过改变的最大流量。
流量守恒:除了源点s和汇点t之外,所有内部节点流入量等于流出量。
源点s:源点主要是流出,但也有可能流入。
源点的净输出值=流出量之和-流入量之和。
汇点t:汇点主要是流入,但也有可能流出。
汇点的净输入值=流入量之和-流出量之和。
对于一个网络可行流flow,净输出等于净输入,这仍然是流量守恒。
网络最大流:在满足容量约束和流量守恒的前提下,在流网络中找到一个净输出最大的网络流。
反向弧:若从u到v的边的容量为c ,这条边上有流量 f 流过(称为正向弧),则相当于v到u有一条容量为0的边,其流量为- f ,这条边就是反向弧。反向弧的作用主要是用于寻找增广路。
反向弧的意义:反向弧的作用是起到有更优决策的时候会使当前选择的弧会自动放弃。反向弧有流量的原因是因为如果刚刚选择了正向弧,下一次如果存在更优策略使这f的流量流入汇点,就可以选择反向弧,将流量 f 撤销。
残余网络:计算出图中的每条边上容量与流量之差(称为残余容量),即可得到残余网络。注意由于反向边的存在,残余网络中的边数可能到达原图中边数的两倍。
观察图下图,这种状态下它的残余网络。
增广路径:残余网络中任何一条从s到t的有向道路都对应一条原图中的增广路径 —— 只要求出该道路中所有残量的最小值d ,把对应的所有边上的流量增加d 即可,这个过程称为增广。
最大流定理:如果残留网络上找不到增广路径,则当前流为最大流;反之,如果当前流不为最大流,则一定有增广路径。
这样的话,求解最大流就只需要在残余网络中寻找增广路,直到不存在可以从s流向t 的增广路,此时即为最大流。求解最大流问题的高效算法有 dinic,sap和isap。
我们今天讲最基础的FF算法与EK算法,他俩的区别在于一个是DFS找增广路,一个是BFS找增广路。后者高效一点。
Edmonds-Karp算法:以广度优先的增广路算法,又称为最短增广路算法(Shortest Augument Panth, SAP)。
最短增广路算法步骤:采用队列q 来存放已访问未检查的结点。布尔数组vis[]标识结点是否被访问过,pre[]数组记录可增广路上结点的前驱。pre[v]=u 表示可增广路上v 结点的前驱是u,最大流值maxflow=0。
- 初始化可行流flow 为零流,即实流网络中全是零流边,残余网络中全是最大容量边(可增量)。初始化vis[]数组为false,pre[]数组为−1。
- 令vis[s]=true,s 加入队列q。
- 如果队列不空,继续下一步,否则算法结束,找不到可增广路。当前的实流网络就是最大流网络,返回最大流值maxflow。
- 队头元素new 出队,在残余网络中检查new 的所有邻接结点i。如果未被访问,则访问之,令vis[i]=true,pre[i]=new;如果i=t,说明已到达汇点,找到一条可增广路,转向第(5)步;否则结点i 加入队列q,转向第(3)步。
- 从汇点开始,通过前驱数组pre[],逆向找可增广路上每条边值的最小值,即可增量d。
- 在实流网络中增流,在残余网络中减流,Maxflow+=d,转向第(2)步。
这里给出EK算法模板:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
const int maxn=1005;
int g[maxn][maxn];//容量
int f[maxn][maxn];//流量
bool vis[maxn];
int pre[maxn];
bool bfs(int s,int t){memset(pre,-1,sizeof pre);memset(vis,false,sizeof vis);queue<int> q;vis[s]=true;q.push(s);while(!q.empty()){int now=q.front();q.pop();for(int i=1;i<=n;i++){if(!vis[i]&&g[now][i]){vis[i]=true;pre[i]=now;if(i==t) return true;q.push(i);}}}return false;
}
int EK(int s,int t){int maxflow=0;int u,v;while(bfs(s,t)){int d=INF;v=t;while(v!=s){u=pre[v];if(d>g[u][v])d=g[u][v];v=u;}maxflow+=d;v=t;while(v!=s){u=pre[v];g[u][v]-=d;g[v][u]+=d;if(f[v][u]>0)f[v][u]-=d;else f[u][v]+=d;v=u;}}return maxflow;
}
int main()
{//int s,t;int u,v,c;while(~scanf("%d%d",&m,&n)){memset(f,0,sizeof f);memset(g,0,sizeof g);for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&c);g[u][v]+=c;}printf("%d\n",EK(1,n));}return 0;
}
图论--网络流最大流问题相关推荐
- 图论-网络流⑦-费用流解题
图论-网络流⑦-费用流解题 上一篇:图论-网络流⑥-费用流 下一篇:图论-网络流⑧-有上下界的网络流 参考文献: https://www.luogu.com.cn/blog/user9012/solu ...
- mysql最小费用最大流问题_图论-网络流之最小费用最大流问题
n=5;C=[0 15 16 0 0 0 0 0 13 14 0 11 0 17 0 0 0 0 0 8 0 0 0 0 0]; %弧容量 b=[0 4 1 0 0 0 0 0 6 1 0 2 0 3 ...
- 0x6A.图论 - 网络流初步
目录 一.网络流基本概念 二.最大流 1)Edmonds−KarpEdmonds-KarpEdmonds−Karp算法 luogu P2740草地排水 Edmonds-Karp增广路,最大流模板 2) ...
- 图论 —— 网络流 —— 基本概念与建模技巧
[基本概念] 1.网络流 给定一个有向图 G=(V,E),在这个图中: 有唯一的一个源点 S(入度为 0,出发点) 有唯一的一个汇点 T(出度为 0,结束点) 图中的每条弧(u,v)都有一非负容量 c ...
- 网络流——最大流问题
老师上课讲的网络流问题,牵扯到几个反相弧,增广路径,残量网络 的概念,愣是一节课神游没听明白,后来只能自己回家搞. 这篇博文我看了以后觉得十分有帮助就拿来了,比较清楚地介绍了它的基本想法思路. htt ...
- 图论 —— 网络流 —— 最小割 —— 平面图与对偶图
[平面图] 对于一个图 G=(V,E),若其重画后,在平面任意两条边的交点除了图中点外,没有其他交点,那么这个图称为平面图 在平面图中,由边包围并且其中不含顶点的区域称为面 包围面 R 的所有边组成的 ...
- 图论 —— 网络流 —— 最大流 —— Dinic 算法
[概述] Dinic 算法在 EK 算法的基础上进行了优化,其时间复杂度为 O(n*n*m). Dinic 在找增广路的时也是找最短增广路, 但与 EK 算法不同的是 Dinic 算法并不是每次 bf ...
- 网络流--最大流问题
一.什么是最大流问题 简单来说,就是在有向网络图中,单位时间内,从开始点到结束点能通过的最大流量 许多应用都包含了流量问题,例如,公路系统中有车辆流,控制系统中有信息流,供水系统中有水流,金融系统中有 ...
- 图论--网络流--最大流 洛谷P4722(hlpp)
题目描述 给定 nn 个点,mm 条有向边,给定每条边的容量,求从点 ss 到点 tt 的最大流. 输入格式 第一行包含四个正整数nn.mm.ss.tt,用空格分隔,分别表示点的个数.有向边的个数.源 ...
最新文章
- Ansible5:Ad-hoc常用模块
- 用神经网络的衰变假设理解神经网络的翻译行为
- 图解+笔记-python语言-第5章:数字/5.3 内置数字工具/5.3.2 内置数学函数
- ES6学习笔记(十六)async函数
- MySQL锁的用法之行级锁
- CSDN-Markdown基本语法
- Android之修改app名字客户需要升级需要注意的问题
- docker没有下载完全_会用Docker的人都别装了,这多简单呐
- win7开机动画自定义
- python zen_The Zen of Python
- VS2008 入门基本操作
- ios系统软件迁移到安卓_苹果系统怎么把文件转到安卓手机?
- 【元胞自动机】基于元胞自动机模拟交通流仿真含Matlab源码
- 傅里叶变换、拉普拉斯变换、Z 变换的联系是什么?为什么要进行这些变换?
- vmware使用自带工具vmware-vdiskmanager精简占用磁盘空间
- 校园综合平台-微信小程序版(整整两个月暑假的成果啊 (•ิ_•ิ))
- ImageView 加载本地(手机)图片
- 《Python与硬件项目案例》— 基于Python与指纹模块AS608的指纹识别签到考勤系统(下篇)(期末大作业、课程设计、毕业设计、结课项目)
- LeetCode 6036. 构造字符串的总得分和
- Win10 平台下, LightGBM GPU 版本的安装
热门文章
- RecyclerView分割线的技巧
- 调用python接口并画图_【PySpark源码解析】教你用Python调用高效Scala接口
- 安卓下载保存到本地(二)
- IOS 企业版发布后,用户通过sarafi浏览器安装无效的解决方案
- java bean 对象属性复制框架BeanMapping-release_0.0.2-注解支持
- Vue.js入门教程-组件注册
- webpack+vue+vueRouter模块化构建完整项目实例详细步骤-入门篇
- platform总线的probe函数调用
- $.each()与$(selector).each()
- 浅析商业银行“业务连续性管理体系”的构建