增广路算法(网络流) HDU1532 Drainage Ditches

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11549

题意&思路:网络流的版题,基本照着小白书打的。

怎么实现增广路,通过正向和反向流量,不断寻找增广路(从起点开始,宽搜压入当前节点的下一节点,用书上术语即层次比当前节点大1的点,类似Dijkstra),当不存在到终点的增广路时,退出。

源码:

#include <cstdio>

#include <cmath>

#include <cstring>

#include <string>

#include <iostream>

#include <algorithm>

#include <vector>

#include <queue>

using namespace std;

int gmin(int a,int b){return a<b?a:b;}

int const inf = 1e8;

int const MAXN = 200+10;

int use[MAXN],c[MAXN][MAXN],flow[MAXN][MAXN],fa[MAXN],n,m;

void init()

{

    memset(flow,0,sizeof(flow));

    int i,j,s,e,val;

    while(m--){

        scanf("%d%d%d",&s,&e,&val);

        flow[s-1][e-1] += val;

    }

}

void solve()

{

    int ans = 0;

    int i,j,k;

    int a[MAXN];

    for(;;){

        memset(use,0,sizeof(use));

        memset(a,0,sizeof a);

        queue<int>q;

        q.push(0);

        a[0] = inf;

        fa[0] = 0; use[0] = 1;

        while(!q.empty()){

            int u = q.front();  q.pop();

            for(i=0; i<n; i++){

                if(use[i]==0 && flow[u][i]>0){

                    use[i] = 1;

                    fa[i] = u;

                    q.push(i);

                    a[i] = gmin(a[u],flow[u][i]);

                }

            }

        }

        if(a[n-1]==0)

            break;

        i = n-1;

        while(i!=0){

            flow[fa[i]][i] -= a[n-1];

            flow[i][fa[i]] += a[n-1];

            i = fa[i];

        }

        ans+=a[n-1];

    }

    printf("%d\n",ans);

}

int main()

{

    while(scanf("%d%d",&m,&n)!=EOF){

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(专题训练)