最大流算法---Ford-Fulkson方法的基本思想与Edmond-Karp算法

来源:互联网 发布:广东电科院待遇 知乎 编辑:程序博客网 时间:2024/05/17 08:17

Ford-Fulkson的具体步骤

1、初始化网络中所有边的容量,c<u,v>继承该边的容量,c<v,u>初始化为0,其中边<v,u>即为回退边。初始化最大流为0。

2、在残留网络中找一条从源S到汇T的增广路p。如能找到,则转步骤3,;如不能找到,则转步骤5。

3、在增广路p中找到所谓的"瓶颈"边,即路径中容量最小的边,记录下这个值X,并且累加到最大流中,转步骤4。

4、将增广路中所有c<u,v>减去X,所有c<v,u>加上X,构成新的残留网络。转步骤2。

5、得到网络的最大流,退出。

Edmond-Karp算法

用朴素的BFS寻找增广路。又称EK算法为最短增广路算法。

#include <iostream>#include <cstdio>#include <queue>#include <cstring>using namespace std;const int INF=1e9;const int maxn=111;//最大点个数int map[maxn][maxn],n,pre[maxn];//map邻接矩阵,n点数,p前驱数组bool EK_bfs(int start,int end);bool EK_bfs(int start,int end){    queue<int>que;//广搜队列    bool visit[maxn];//标记数组    memset(visit,0,sizeof(visit));    memset(pre,-1,sizeof(pre));    que.push(start);    visit[start]=true;    while (!que.empty())    {        int u=que.front();        if (u==end) return true;//增广路找到        que.pop();        for (int v=1;v<=n;v++)        {            if (map[u][v]&&!visit[v])//边容量非零且增广点未标记            {                visit[v]=true;                pre[v]=u;//记录前驱                que.push(v);//入队            }        }    }    return false;}int EK_max_flow(int start,int end){    int u,flow_ans=0,mn;//初始化最大流为0    while (EK_bfs(start,end))//当增广成功    {        mn=INF;        u=end;        while (pre[u]!=-1)//寻找瓶颈边并记录容量        {            mn=min(mn,map[ pre[u] ][ u ]);            u=pre[u];        }        flow_ans+=mn;//累加进最大流        u=end;        while (pre[u]!=-1)//修改路径上的边容量        {            map[ pre[u] ][ u ]-=mn;            map[ u ][ pre[u] ]+=mn;            u=pre[u];        }    }    return flow_ans;}


原创粉丝点击