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

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;
}


你可能感兴趣的:(资料,图论)