网络流--最大流问题
Posted -citywall123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流--最大流问题相关的知识,希望对你有一定的参考价值。
一、什么是最大流问题
简单来说,就是在有向网络图中,单位时间内,从开始点到结束点能通过的最大流量
许多应用都包含了流量问题,例如,公路系统中有车辆流,控制系统中有信息流,供水系统中有水流,金融系统中有现金流等等
二、简单概念
1、源点:出发点。
2、汇点:结束点。
3、流:就是一条可以从源点到汇点的一条合法路径。
4、容量:每条边都有一个容量(水管的最大水流容量)
5、流量:就是一条可以从源点到汇点的一条合法路径能通过的最大数量,大小取决于这条路径上的最小容量
6、增广路:也就是流,一条可以从源点到汇点的一条合法路径
7、残量:就是剩余容量,对于一条边来说,残量=容量-流量
三、求最大流的过程
下图是一个交通运输网络,有1到6共6个结点,两个结点间的数字代表它们之间的最大运输能力,求结点1到结点6在单位时间内的最大运输能力(流量)?
可以看到结点1到结点6之间有多条路径,而所有路径的最大流量之和正是所要求的最大流量,问题转化为求每条路径的最大流量,以路径:1-3-5-6为例,结点间的运输流量分别是10、14、21,容易想到10是这条路径的瓶颈,所以1-3-5-6的最大运行能力是10。同时也意味着,当1-3之间达到运输瓶颈10时,1-3这条路就不再具备运输能力了(就可以把1-3条路从图中去掉了,同时也要把3-5-6路径上的运输能力减掉10,因为已经被我们找到的第一条路径给占用了10,这样就有了下图),记录下第一条路径的最大流量10。
下面继续找一条路径:1-2-5-6,它的剩余最大流量是6。按照上面的方法去掉1-2,并把2-5-6的运输能力减6,就有了下图:
接下来是:1-4-6,它的剩余最大流量是5。
接下来是:1-4-3-5-6,它的剩余最大流量是1。
接下来是:1-4-2-5-6,它的剩余最大流量是1。
至此结点1到6之间已经没有通路了,把各个路径的最大流量和加起来即是所求:10+6+5+1+1=23
以上转载自:https://www.jianshu.com/p/e4548c5c381e
反向边的概念
四、代码实现(EK算法)
时间复杂度:O(n*m2),m是边数,n是顶点数量
注意:在读入边的时候,要注意重边的情况,要用加法存边
int flow[205][205],cap[205][205];//flow当前流量,cap总容量 int f[205],vis[205];//f[i]最小残量=cap-flow,vis[i]标记i节点的上一个最小残量所在的位置 int mx_flow;//最大流量,所有增广路最小残量之和 void bfs(int n) queue<int>p; mx_flow=0; int flag=0; memset(flow,0,sizeof(flow)); while(flag==0) memset(f,0,sizeof(f)); memset(vis,0,sizeof(vis)); f[1]=mx,vis[1]=-1;//初始化源点 p.push(1); while(!p.empty())//bfs找增广路 int now=p.front(); p.pop(); for(int i=1;i<=n;i++) if(!f[i]&&flow[now][i]<cap[now][i]) f[i]=min(f[now],cap[now][i]-flow[now][i]);//取最小残量 vis[i]=now; p.push(i); if(f[n]==0)//容量-流量==0,一条增广路寻找结束 flag=1; mx_flow+=f[n]; int pos=n;//从汇点开始更新流量 while(!flag&&pos!=1) flow[vis[pos]][pos]+=f[n];//正向更新流量 flow[pos][vis[pos]]-=f[n];//反向更新流量 pos=vis[pos];
模板题:https://www.cnblogs.com/-citywall123/p/11322765.html
以上是关于网络流--最大流问题的主要内容,如果未能解决你的问题,请参考以下文章