zoukankan      html  css  js  c++  java
  • 最大流算法完整代码

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

      

  • 相关阅读:
    PVS 7.6 部署教程
    PHP下载远程图片的3个方法
    [Xcode 实际操作]二、视图与手势-(2)UIView视图的层次关系
    [Swift]检查API可用性
    [Xcode 实际操作]二、视图与手势-(1)UIView视图的基本使用
    [Swift]LeetCode103. 二叉树的锯齿形层次遍历 | Binary Tree Zigzag Level Order Traversal
    [Swift]forEach详解
    [Swift]LeetCode937. 重新排列日志文件 | Reorder Log Files
    [Swift]LeetCode940. 不同的子序列 II | Distinct Subsequences II
    [Swift]LeetCode939. 最小面积矩形 | Minimum Area Rectangle
  • 原文地址:https://www.cnblogs.com/eternalwt/p/3648518.html
Copyright © 2011-2022 走看看