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