hdu 1532 网络流EK模版

/*
题意:给出排水沟的图,以及沟渠流量,求最大流出速率

题解:最大流,EK算法,完全模版;
*/
#include <iostream>
#include <cstring>
#include <queue>

#define EMAX 405
#define VMAX 205

using namespace std;

int EN;//边的总数

int head[VMAX];//用邻接表表示图
int pre[VMAX];//记录路径
int path[EMAX];//记录该点边的位置
struct edge
{
    int to;
    int weight;//流量
    int next;
}e[EMAX];

void insert(int u, int v, int w)
{
    e[EN].next = head[u];
    e[EN].to = v;
    e[EN].weight = w;
    head[u] = EN++;
    e[EN].next = head[v];
    e[EN].to = u;
    e[EN].weight = 0;//需要插入反向边
    head[v] = EN++;
}

int flow_ek(int s, int t)
{
    queue<int> Q;
    int ret = 0;
    while (true)
    {
        memset(pre,-1,sizeof(pre));
        while (!Q.empty())
            Q.pop();
        Q.push(s);
        while (!Q.empty())//BFS
        {
            int u = Q.front();
            Q.pop();
            for(int i=head[u]; i!=-1; i=e[i].next)
            {
                if (pre[e[i].to]==-1 && e[i].weight>0)
                {
                    pre[e[i].to] = u;//记录路径
                    path[e[i].to] = i;//记录该点边的所在位置,方便后面直接查询
                    Q.push(e[i].to);
                }
            }
            if (pre[t] != -1)//终点的pre不为-1,表示找到一条增广路径
                break;
        }
        if (pre[t] == -1)//当BFS后找不到增广路径则结束循环
            break;
        int mw = -1;
        for(int v=t; v!=s; v=pre[v])//找出当前路径中的流量的最小容量
        {
            if (mw == -1 || mw > e[path[v]].weight)
                mw = e[path[v]].weight;
        }
        for(int v=t; v!=s; v=pre[v])//修改路径的容量,求出残余网络
        {
            e[path[v]].weight -= mw;
            e[path[v]^1].weight += mw;//更新逆向边
        }
        ret += mw;
    }
    return ret;
}

int main(void)
{
    int n,m,a,b,c;
    while (cin >> n >> m)
    {
        memset(head,-1,sizeof(head));
        EN = 0;
        for(int i=0; i<n; i++)
        {
            cin >> a >> b >> c;
            insert(a,b,c);
        }
        cout << flow_ek(1,m) << endl;
    }
    return 0;
}

 

posted @ 2014-03-20 23:43  辛力啤  阅读(165)  评论(0编辑  收藏  举报