看过的最大流算法中,薛超英教授的《数据结构》第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; }