C++ 最大流(push-relable)算法

// The push-relable algorithm code due to CLRS chapter 26
#include<iostream>
#include<list>
using namespace std;
const int N = 100;
int n; // vertex number
int e[N]; // residual flow of the vertex
int h[N]; // height of the vertex
int c[N][N]; // capacity of the edge
int f[N][N]; // flow of the edge
list<int> ev; // excess flow vertex
list<int> edge[N]; // edge link list
bool flag[N]; // lable whether the vertex is in the flow list

inline void Push(int u, int v) // push flow from edge (u, v)
{
    int df = min(e[u], c[u][v] - f[u][v]);
    f[u][v] += df;
    f[v][u] = -f[u][v];
    e[u] -= df;
    e[v] += df;
}

void Relable(int u) // re-lable heght of vertex u
{
    h[u] = n * 2 - 1;
    for(list<int>::iterator iter = edge[u].begin(); iter != edge[u].end(); iter++)
    {
        if(c[u][*iter] > f[u][*iter] && h[*iter] < h[u])
            h[u] = h[*iter];
    }
    h[u]++;
}

void Discharge(int u) // discharge the residual flow of vertex u
{
    list<int>::iterator iter = edge[u].begin();
    while(e[u] > 0)
    {
           if(iter == edge[u].end())
        {
            Relable(u);
            iter = edge[u].begin();
        }
        if(h[u] == h[*iter] + 1 && c[u][*iter] > f[u][*iter])
        {
            Push(u, *iter);
            if(e[*iter] > 0 && !flag[*iter])
                ev.push_back(*iter);
        }
        ++iter;
    }
}

void Init_PreFlow()
{
    ev.clear();
    h[0] = n;
    e[0] = 0;
    memset(flag, 0, sizeof(flag));
    memset(f, 0 , sizeof(f));
    flag[0] = flag[n-1] = true;
    for (int u = 1; u < n; u++)
    {
        f[0][u] = c[0][u];
        f[u][0] = -f[0][u];
        e[u] = c[0][u];
        if(e[u] > 0 && !flag[u])
        {
            ev.push_back(u);
            flag[u] = true;
        }
    }

    // construct link list
    for(int u = 0; u < n; u++)
        for(int v = u + 1; v < n; v++)
        {
            if(c[u][v] > 0 || c[v][u] > 0)
            {
                edge[u].push_back(v);
                edge[v].push_back(u);
            }
        }
}

int Push_Relable()
{
    Init_PreFlow();
    while(!ev.empty())
    {
        int u = ev.front();
        Discharge(u);
        ev.pop_front();
        flag[u] = false;
    }
    return e[n-1];
}

int main()
{
    int m, u, v, w;
    while(scanf("%d%d", &m, &n) != EOF)
    {
        memset(c, 0, sizeof(c));
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            c[u][v] = w;
        }
        printf("Max Flow is %d\n", Push_Relable());
    }
    return 0;
}

轉自: http://www.cnblogs.com/ltang/archive/2011/05/07/2039687.html



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章