Ford-Fulkerson方法求最大流

来源:互联网 发布:carnet.it 编辑:程序博客网 时间:2024/04/29 15:19

本文试图用通俗的说法描述这个最大流算法,有关名称的准确定义请您参考其他资料


Ford-Fulkerson方法(G,s,t )

    初始化最大流f等于0

    while 在残存网络里存在一条增广路径

        根据 该增广路径 更新最大流f 以及残存网络 

return f 


    边的残存容量:原来的图中的每条边都有一个容量,随着算法的实施,在一些时刻有些边允许的容量在减小,而有些时候一些边的容量在增加,换句话说,在求最大流的过程中,图中的边的容量是变化的,于是用残存容量来刻画一条边在当前状态还能通过的流量。残存容量大于零的边构成残存网络残存网络中从源点s到汇点t的一条简单路径称为增广路径


    每次寻求一条增广路企图增加从源点到汇点的流量。由于采用BFS搜索,所以能够保证每次找到的增广路是最短的。每次寻求增广路的过程中,使用r [ u ] 来存储表示从源点到达 u 点的最大可能的流量,假设我们的搜索路径中有这样的一条边 (u ,v)。那么,r [u ]= min( r[u] , (u,v)的残存容量 )。


下面是一小组测试数据以及程序,之后,将给出程序运行的图解。在结尾,简单地分析一下算法的正确性以及时间复杂度,并附带图中所使用的样例,以方便您进行测试。


核心代码的导引:

while(1){设置从源点到图中每一点的最大流量为零源点入队Q,设置源点到源点的最大流量为无穷大while(!Q.empty()){int u=Q.front();Q.pop();for(int v=1;v<=n;v++){if(v还没被访问过并且u到v的残存容量大于零){r[v]=min(r[u],u到v的残存容量);Q.push(v);pa[v]=u;}}}if(源点到汇点的流量为零)break;for(int u=t;u!=s;u=pa[u]){更新正向残存容量;更新反向残存容量;}f+=r[t];}


#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<iostream>#define maxn 100#define INF 100000000using namespace std;int cap[maxn+10][maxn+10];//容量int flow[maxn+10][maxn+10];//流量int r[maxn+10];//最小残存容量int pa[maxn+10];//记录增广路 int s,t,n,m;queue<int> Q;int BFS(int s,int t){int f=0;memset(flow,0,sizeof(flow));while(1){memset(r,0,sizeof(r));memset(pa,0,sizeof(pa));Q.push(s);r[s]=INF;while(!Q.empty()){int u=Q.front();Q.pop();for(int v=1;v<=n;v++){if(!r[v]&&cap[u][v]>flow[u][v]){r[v]=min(r[u],cap[u][v]-flow[u][v]);Q.push(v);pa[v]=u;}}}if(r[t]==0)break;for(int u=t;u!=s;u=pa[u]){flow[pa[u]][u]+=r[t];flow[u][pa[u]]-=r[t];}f+=r[t];}return f;  }int main(){freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);scanf("%d%d",&n,&m);memset(cap,0,sizeof(cap));for(int i=0;i<m;i++){int u,v,c;scanf("%d%d%d",&u,&v,&c);cap[u][v]=c;}scanf("%d%d",&s,&t);printf("%d\n",BFS(s,t));return 0;}





















    算法的正确性不难说明,程序结束时,残存网络中已经不含增广路,此时的流量f即是G的一个最大流。通过反正,假设f是G的最大流,同时残存网络中还有一条增广路p,我们就可以用p来更新最大流得到更大的最大流。由于每次寻路都会将流量至少增加1个单位,那么while 循环至多执行f次,这里f是最大流量。使用广度优先搜索算法寻找最短路径,时间是O(E)。所以总的时间复杂度是O(f*E)。

6 9
1 2 16
1 3 13
2 3 10
2 4 12
3 2 4
3 5 14
4 3 9 
4 6 20
5 6 4
1 6


0 0
原创粉丝点击