网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。网络流的理论和应用在不断发展。而我们今天要讲的就是网络流里的一种常见问题——最大流问题。

最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。求最大流的标号算法最早由福特和福克逊与与1956年提出,20世纪50年代福特(Ford)、(Fulkerson)建立的“网络流理论”,是网络应用的重要组成成分。

再解决这个问题前,我们要先弄懂一些定义

网络流图是一张只有一个源点和汇点的有向图,而最大流就是求源点到汇点间的最大水流量,下图的问题就是一个最基本,经典的最大流问题

二.流量,容量和可行流

对于弧(u,v)来说,流量就是其上流过的水量(我们通常用f(u,v)表示),而容量就是其上可流过的最大水量(我们通常用c(u,v)表示),只要满足f(u,v)<=c(u,v),我们就称流量f(u,v)是可行流(对于最大流问题而言,所有管道上的流量必须都是可行流)。

三.增广路

如果一条路上的所有边均满足:

正向边: f(u,v)< c(u,v) ——– 反向边:f(u,v)> 0

假如有这么一条路,这条路从源点开始一直一段一段的连到了汇点,并且,这条路上的每一段都满足流量<容量,注意,是严格的<,而不是<=。那么,我们一定能找到这条路上的每一段的(容量-流量)的值当中的最小值delta。我们把这条路上每一段的流量都加上这个delta,一定可以保证这个流依然是可行流。这样我们就得到了一个更大的流,他的流量是之前的流量+delta,而这条路就叫做增广路. From 网络流(Network Flow)

则我们称这条路径为一条增广路径,简称增广路。

好了,弄懂了一些定义,接下来就可以介绍著名的Ford-Fulkerson算法了。

如图所示,如果我们每次都找出一条增广路,只要这条增广路经过汇点,那说明此时水流还可以增加,增加的量为d(d=min(d,c(u,v)-f(u,v))或d=min(d,f(u,v)))。

我们可以这样理解:对于每一条正向边,他能添加的最大水流为c(u,v)-f(u,v)。而对于反向边来说,当正向边上的水流增多时,反向边自身的反向水流会减少,而其能减少的最多水量为f(u,v)。由于要保证添加水流之后,所有的f(u,v)都是可行流,所以我们取最小值。

增加之后,我们要更新流量,每条正向边+d,每条反向边-d即可。

既然这样,我们的思路就是:

1.找出一条增广路径 ——2.修改其上点的值——3.继续重复1,直至找不出增广路。则此时源点的汇出量即为所求的最大流。

那么上代码:

#include<bits/stdc++.h>
#include<vector>
#define maxn 1200
#define INF 2e9
using namespace std;
int i,j,k,n,m,h,t,tot,ans,st,en;
struct node{
int c,f;
}edge[maxn][maxn];
int flag[maxn],pre[maxn],alpha[maxn],q[maxn],v;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
} void bfs(){
memset(flag,0xff,sizeof(flag));memset(pre,0xff,sizeof(pre));memset(alpha,0xff,sizeof(alpha));
flag[st]=0;pre[st]=0;alpha[st]=INF;h=0,t=1;q[t]=st;
while(h<t){
h++;v=q[h];
for(int i=1;i<=n;i++){
if(flag[i]==-1){
if(edge[v][i].c<INF&&edge[v][i].f<edge[v][i].c){
flag[i]=0;pre[i]=v;alpha[i]=min(alpha[v],edge[v][i].c-edge[v][i].f);q[++t]=i;
}
else if(edge[i][v].c<INF&&edge[i][v].f>0){
flag[i]=0;pre[i]=-v;alpha[i]=min(alpha[v],edge[i][v].f);q[++t]=i;
}
}
}
flag[v]=1;
}
} void Ford_Fulkerson(){
while(1){
bfs();
if(alpha[en]==0||flag[en]==-1){
break;
}
int k1=en,k2=abs(pre[k1]);int a=alpha[en];
while(1){
if(edge[k2][k1].c<INF) edge[k2][k1].f+=a;
else if(edge[k1][k2].c<INF) edge[k1][k2].f-=a;
if(k2==st) break;
k1=k2;k2=abs(pre[k1]);
}
alpha[en]=0;
}
} void flow(){
int maxflow=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==st&&edge[i][j].f<INF) maxflow+=edge[i][j].f;
}
printf("%d",maxflow);
} int main(){
int u,v,c,f;
n=read();m=read();st=read();en=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) edge[i][j].c=INF,edge[i][j].f=0;
for(int i=1;i<=m;i++){
u=read();v=read();c=read();
edge[u][v].c=c;
}
Ford_Fulkerson();
flow();
return 0;
}

网络流的最大流入门(从普通算法到dinic优化)的更多相关文章

  1. 网络流 最大流—最小割 之SAP算法 详解

    首先引入几个新名词: 1.距离标号: 所谓距离标号 ,就是某个点到汇点的最少的弧的数量(即边权值为1时某个点到汇点的最短路径长度). 设点i的标号为level[i],那么如果将满足level[i]=l ...

  2. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  3. 最大流算法之Dinic

    引言: 在最大流(一)中我们讨论了关于EK算法的原理与代码实现,此文将讨论与EK算法同级别复杂度(O(N^2M))的算法--Dinic算法. Dinic算法用到的思想是图的分层结构,通过BFS将每一个 ...

  4. ISAP算法对 Dinic算法的改进

    ISAP算法对 Dinic算法的改进: 在刘汝佳图论的开头引言里面,就指出了,算法的本身细节优化,是比较复杂的,这些高质量的图论算法是无数优秀算法设计师的智慧结晶. 如果一时半会理解不清楚,也是正常的 ...

  5. SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。

    这里的高斯模糊采用的是论文<Recursive implementation of the Gaussian filter>里描述的递归算法. 仔细观察和理解上述公式,在forward过程 ...

  6. 小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)--转载

    小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)   在上回<小波学习之一>中,已经详细介绍了Mallat算法C++实现,效果还可以,但也存在一些问题,比如,代码 ...

  7. 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)

    [题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...

  8. Java 排序算法-冒泡排序及其优化

    Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...

  9. 网络流_Edmond-Karp算法、Dinic算法

    转载:网络流基础篇——Edmond-Karp算法             BY纳米黑客 网络流的相关定义: 源点:有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点. 汇点:另一个点也很特殊, ...

随机推荐

  1. spring整合web项目

    Web项目如何初始化SpringIOC容器 :思路:当服务启动时(tomcat),通过监听器将SpringIOC容器初始化一次(该监听器 spring-web.jar已经提供),web项目启动时 ,会 ...

  2. 【SSM】Log4j 日志配置

    1.log4j.properties ### 配置根 ### # log4j.rootLogger = debug,console ,fileAppender,dailyRollingFile,ROL ...

  3. 【PAT甲级】1003 Emergency (25 分)(SPFA,DFS)

    题意:n个点,m条双向边,每条边给出通过用时,每个点给出点上的人数,给出起点终点,求不同的最短路的数量以及最短路上最多能通过多少人.(N<=500) AAAAAccepted code: #in ...

  4. 第二章linux网络基础设置总结!

    一:查看及测试网络 (1)查看活动的网络接头命令:ifconfig (2)查看所有网络接口命令:ifconfig -a (3)查看指定的网络接口(不论该网络接口是否处于激活状态)命令:ifconfig ...

  5. Linux Mysql基础操作

    1). 打开MySQL 使用如下两条命令,打开MySQL服务并使用root用户登录: # 启动 MySQL 服务 sudo service mysql start # 使用 root 用户登录,实验楼 ...

  6. PB specified database is invalid

    拷贝资料库到其他机器,可以重新配置ODBC ,如果还是报错,建议删除log .

  7. jquery中for循环

    1.循环遍历标签 //定义数组 var imagesPath=[]; //循环遍历对象 $("#uploadList li img").each(function(){ image ...

  8. TimeSeriesEditor时间序列编辑软件之实战ReoGrid表格控件和Zedgraph绘图控件

    最近用ReoGrid表格控件和Zedgraph绘图控件写了一个TimeSeriesEditor时间序列编辑软件,如下图. 目的就是体验一下这两个空间的用法,感觉还是挺好用的, 关于软件的使用说明可以访 ...

  9. 【LOJ3087】「GXOI / GZOI2019」旅行者

    题意 给定一个 \(n\) 个点 \(m\) 条边的的有向图,给出 \(k\) 个关键点,求关键点两两最短路的最小值. \(n\le 10^5, m\le 5\cdot 10^5\). 题解 二进制分 ...

  10. 小程序云开发使用where查询遇到的问题

    想用小程序云开发的where查询,结果不论输入什么都是不报错,开始没注意,后来发现输入数据库中有的数据时,给打印出来查询成功,输入数据库中没有的数据时,也会得到一个集合,只不过这个集合的长度为0而已. ...