最大流算法---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; }