看过的最大流算法中,薛超英教授的《数据结构》第5章应该是讲的比较易懂的,里面没有一开始就上来一堆符号。在线阅读地址:
http://max.book118.com/html/2012/0630/2313684.shtm
http://www.doc88.com/p-407189007451.html
书中提供的算法属于未经优化的Ford-Fulkerson算法,可以学会此方法后再学习其他方法。算法原理是:
Ford-Fulkerson 方法 (G,s,t)
1 将各边上流量 f 初始化为 0
2 while 存在一条增广路径 p
3 do 沿路径 p 增广流量 f
4 return f
上面提到的书写的很通俗,但是个人感觉有个问题是第5章图算法安排的位置有点靠前。另外作者是学院派写代码有2点不好的地方:一是经常用单个字母命名变量,这样带来的最大问题是当用Ctrl+F查找变量时,难以查找;二是比较喜欢用do-while循环,可读性没有for好。另外我写算法喜欢把输入数据直接写在初始化代码中,便于检查算法效果和调试。
下面是根据书中算法写的代码:
#include<iostream>
#include<cmath>
using namespace std;
const int SCALE=6;
int matrix[SCALE][SCALE]={0};
int flow[SCALE][SCALE]={0};
int stk[SCALE]={0};
void init()
{
matrix[0][1]=4;
matrix[1][2]=4;
matrix[2][3]=2;
matrix[4][3]=6;
matrix[4][5]=9;
matrix[0][2]=8;
matrix[2][4]=2;
matrix[3][5]=7;
matrix[1][3]=4;
matrix[1][4]=1;
}
int findPath()
{
int mark[SCALE];
for(int i=0;i<SCALE;i++)mark[i]=0;
int top=0;
stk[top]=0;
mark[top]=1;
while(top>=0)
{
int current=abs(stk[top]);
int i=0;
for(i=0;i<SCALE;i++)
{
if(mark[i]==0)
{
if(matrix[current][i]>flow[current][i])
{
top+=1;
stk[top]=i;
mark[i]=1;
if(i==(SCALE-1))
{
return top;
}
break;
}
else if(flow[i][current]>0)
{
top+=1;
stk[top]=(-i);
mark[i]=1;
break;
}
}
}
if(i==SCALE)
{
top=top-1;
}
}
return 0;
}
void update(int top)
{
int addValue=65535;
for(int i=1;i<=top;i++)
{
int temp=0;
int first=abs(stk[i-1]);
int second=abs(stk[i]);
if(stk[i]>0)
{
temp=matrix[first][second] - flow[first][second];
}
else
{
temp=flow[second][first];
}
if(addValue>temp)
{
addValue=temp;
}
}
for(int i=1;i<=top;i++)
{
int first=abs(stk[i-1]);
int second=abs(stk[i]);
if(stk[i]>0)
{
flow[first][second] = flow[first][second]+addValue;
}
else
{
flow[second][first] = flow[second][first]-addValue;
}
}
}
int maxFlow()
{
int val=0;
while((val=findPath())>0)update(val);
int maxVolumn=0;
for(int i=1;i<SCALE;i++)
{
maxVolumn += flow[0][i];
}
return maxVolumn;
}
int main()
{
init();
cout<<maxFlow();
return 0;
}