最短增广路算法

来源:互联网 发布:昵称特殊字符 数据库 编辑:程序博客网 时间:2024/05/23 10:55

面试的时候被问到了,然后没答上,这几天就看了看

可以结合这两个地方来看

http://wenku.baidu.com/view/1ed7ebebe009581b6bd9eb97.html

http://www.cnblogs.com/ACAC/archive/2010/05/18/1738719.html



#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
#define MAX_NUM 1024

int cap[MAX_NUM][MAX_NUM]; //残缺网络
int d[MAX_NUM] ; //标号
int num[MAX_NUM];   //对每个标号计数,用于间隙优化
int pre[MAX_NUM] ; //记录结点
int s,t; //源点  汇点
int m,n;  //点的个数    //边的个数

bool ReadDataFromFile(const char *filename)
{
    ifstream file(filename,ios::in);
    if(!file)
    {
        return false;
    }
    file >> s >> t;
    cout<<s<<" "<<t<<endl;
    file >> m >> n;
    cout<<m<<" "<<n<<endl;
    int x,y,tempCap;
    for(int i = 0 ; i < n ; i++ )
    {
        file >> x >> y >> tempCap;
        cap[x][y] = tempCap;
        cout<<x<<" "<<y<< " "<< cap[x][y]<<endl;
    }
    file.close();
    return true;
}

void Init_d()
{
    memset(d,1,sizeof(d));
    memset(num,0,sizeof(num));
    queue<int> list;
    list.push(t);
    d[t] = 0;
    num[0] = 1;
    while(!list.empty())
    {
        int v = list.front();
        list.pop();
        for(int u = 0 ; u < m ; u++ )
        {
            if( d[u] >=m  && cap[u][v] > 0 )
            {
                d[u] = d[v]+1;
                num[ d[u] ]++;
                list.push(u);
            }
        }
    }
    cout<<endl;
}

int Reliable(int i)
{
    int m1 = INT_MAX;
    for(int j = 0 ; j < m ; j++ )
    {
        if(cap[i][j] > 0 && d[j]+1<m1 )
        {
            m1 = d[j]+1;
        }
    }
    return m1 == INT_MAX?m:m1;
}

int FindAllow(int i)
{
    for(int j = 0 ; j<m ; j++ )
    {
        if( cap[i][j] > 0 && d[i] == d[j]+1 )
            return j;
    }
    return -1;
}

int GetMaxFlow(int s,int t)
{
    int maxFlow = 0;
    memset(pre,-1,sizeof(pre));
    int j = s;
    while( d[s] < m )
    {
        int i = FindAllow(j);
        if( i != -1 )
        {
            pre[i] = j;
            j = i ;
            if( i == t )
            {
                int dele = INT_MAX;
                for( j = t ; j != s ; j = pre[j] )
                {
                    if(dele > cap[ pre[j] ][ j ] )
                        dele = cap[ pre[j] ][ j ];
                }
                for( j = t ; j != s ; j = pre[j] )
                {
                     cout<< pre[j]<<" "<<j<<" "<<cap[ pre[j] ][ j ]<<" "<<dele<<endl;

                     cap[ pre[j] ][ j ] -= dele;
                     cap[ j ][ pre[j] ] += dele;
                }
                maxFlow+=dele;
            }
            continue;
        }else{
            int tempI = Reliable(j);
            num[ tempI ]++;
            num[ d[j] ]--;
            if( num[ d[j] ] == 0 )
            {
                return maxFlow;
            }
            d[j] = tempI;
            if( j != s  )
            {
                j = pre[j];
            }
        }
    }
    return maxFlow;
}

int main()
{
    cout <<"start" << endl;
    ReadDataFromFile("E:\\Test.txt");
    Init_d();
    int maxFlow = GetMaxFlow(s,t);
    cout<<maxFlow<<endl;
    cout <<"end"<< endl;
    return 0;
}


原创粉丝点击