POJ 1273 Drainage Ditches

题意:一个人修了一个水渠(有向连通图),每条边有能通过的最大流量,问从起点到终点,最多能运输多少水。

解法:最大流问题。最大流的入门题,也是我做的第一个最大流题目,阅读了刘汝佳的小白和kuangbin大神的博客……

使用的是Edmonds-Karp算法,用bfs搜索一条路,记录这条路的路径和通过的最大流量,更新残余网络,再bfs下一条路径,直到搜不到一条路径为止。

搜索路径的时候要关注已通过流量是否达到最大流量,如果达到则不能走这条路,并记录此路径本次搜索能通过的最大流量,由于这个标记一定不为0,所以可以当作visit数组。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
int main()
{
    int cap[205][205];//邻接矩阵,每个边能通过的最大流量
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        memset(cap, 0, sizeof(cap));
        for(int i = 0; i < n; i++)
        {
            int u, v, f;
            scanf("%d%d%d", &u, &v, &f);
            cap[u][v] += f;//输入会出现重复边,值需要累加(被坑了好久)
        }
        int a[205], p[205], flow[205][205];//a记录一条路径中每个点通过的最大流量
                                             p记录路径
                                             flow邻接矩阵,记录残余网络
        memset(flow, 0, sizeof(flow));
        int ans = 0;
        while(1)
        {
            queue <int> q;
            memset(a, 0, sizeof(a));
            a[1] = INT_MAX;
            q.push(1);
            while(!q.empty())//bfs
            {
                int u = q.front();
                q.pop();
                bool flag = false;
                for(int v = 1; v <= m; v++)
                {
                    if(!a[v] && (cap[u][v] > flow[u][v]))
                    {
                        q.push(v);
                        a[v] = min(a[u], cap[u][v] - flow[u][v]);
                        p[v] = u;
                        if(v == m)
                        {
                            flag = true;
                            break;
                        }
                    }
                }
                if(flag)//搜索到终点后结束
                    break;
            }
            if(!a[m])//如果搜不到终点,说明已经是最大流
                break;
            ans += a[m];
            for(int i = m; i != 1; i = p[i])//更新残余网络
            {
                flow[p[i]][i] += a[m];
                flow[i][p[i]] -= a[m];
            }
        }
        printf("%d
", ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Apro/p/4421589.html