网络流问题——最大流 POJ 1273

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HZEUHJEJNJ/article/details/80086183

例题POJ 1273

Every time it rains on Farmer John’s fields, a pond forms over Bessie’s favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage ditches so that Bessie’s clover patch is never covered in water. Instead, the water is drained to a nearby stream. Being an ace engineer, Farmer John has also installed regulators at the beginning of each ditch, so he can control at what rate water flows into that ditch.
Farmer John knows not only how many gallons of water each ditch can transport per minute but also the exact layout of the ditches, which feed out of the pond and into each other and stream in a potentially complex network.
Given all this information, determine the maximum rate at which water can be transported out of the pond and into the stream. For any given ditch, water flows in only one direction, but there might be a way that water can flow in a circle.

Input

The input includes several cases. For each case, the first line contains two space-separated integers, N (0 <= N <= 200) and M (2 <= M <= 200). N is the number of ditches that Farmer John has dug. M is the number of intersections points for those ditches. Intersection 1 is the pond. Intersection point M is the stream. Each of the following N lines contains three integers, Si, Ei, and Ci. Si and Ei (1 <= Si, Ei <= M) designate the intersections between which this ditch flows. Water will flow through this ditch from Si to Ei. Ci (0 <= Ci <= 10,000,000) is the maximum rate at which water will flow through the ditch.

Output

For each case, output a single integer, the maximum rate at which water may emptied from the pond.

Sample Input

5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10

Sample Output

50

网络流问题(来自北京大学ACM暑期课讲义–郭炜)

给定一个有向图G=(V,E),把图中的边看作管道,每条边上有一个权值,表示该管道的流量上限。给定源点s和汇点t,现在假设在s处有一个水源,t处有一个蓄水池,问从s到t的最大水流量是多少
这里写图片描述
基本思路很简单,每次用dfs从源到汇找一条可行路径, 然后把这条路塞满。这条路径上容量最小的那条边的容量,就是这次dfs所找到的流量。然后对于路径上的每条边,其容量要减去刚才找到的流量。对上次dfs时找到的流量路径上的边,添加一条“反向”边,反向边上的容量等于上次dfs时找到的该边上的流量,然后再利用“反向”的容量和其他边上剩余的容量寻找路径。当再次进行dfs,已经找不到路径了,所以流量无法再增加,此即为最大流。

残余网络

在一个网络流图上,找到一条源到汇的路径(即找到了一个流量)后,对路径上所有的边,其容量都减去此次找到的流量,对路径上所有的边,都添加一条反向边,其容量也等于此次找到的流量,这样得到的新图,就称为原图的“残余网络”

Edmonds-Karp算法

求最大流的过程,就是不断找到一条源到汇的路径,然后构建残余网络,再在残余网络上寻找新的路径,使总流量增加,然后形成新的残余网络,再寻找新路径…..直到某个残余网络上找不到从源到汇的路径为止,最大流就算出来了。
每次寻找新流量并构造新残余网络的过程,就叫做寻找流量的“增广路径”,也叫“增广”。在每次增广的时候,选择从源到汇的具有最少边数的增广路径,即不是通过dfs寻找增广路径,而是通过bfs寻找增广路径。已经证明这种算法的复杂度上限为nm2 (n是点数,m是边数)。

分析

此处采用领接矩阵来存储相关数据。
赤裸裸的网络流题目。
解题过程和上面分析的过程一摸一样。

样例实现代码

/*
 ZhangBinjie@Penguin
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 205 
using namespace std;
long long G[maxn][maxn];
bool vis[maxn];
int pre[maxn];
int n,m;
long long Karp(){
    int v;
    queue<int>q;
    bool findp = false;
    memset(pre,0,sizeof(pre));
    memset(vis,false,sizeof(vis));
    vis[1]=true;
    pre[1]=0;
    q.push(1);
    while(!q.empty()){
        v=q.front();
        q.pop();
        for(int i=1;i<=m;++i){
            if(vis[i]==0&&G[v][i]>0){
                pre[i]=v;
                vis[i]=true;
                if(i==m){
                    findp=true;
                    while(!q.empty())
                        q.pop();
                    break;
                }
                else
                    q.push(i);
            }
        }
    }
    if(findp=false)
        return 0;
    long long minf = G[pre[m]][m];
    v=pre[m];
    while(pre[v]){
        minf = min(minf,G[pre[v]][v]);
        v=pre[v];
    }
    v=m;
    while(pre[v]){
        G[pre[v]][v] -= minf;
        G[v][pre[v]] += minf;
        v = pre[v];
    }
    return minf;
}
int main(){
    int from,to,cap;
    long long maxf,aug;
    while(cin>>n>>m){
        maxf = 0;
        memset(G,0,sizeof(G));
        for(int i=0;i<n;++i){
            cin>>from>>to>>cap;
            G[from][to]+=cap;
        }
        while(aug=Karp()){
            maxf += aug;
        }
        cout<<maxf<<endl;
    }
    return 0;
}

结果

这里写图片描述

猜你喜欢

转载自blog.csdn.net/HZEUHJEJNJ/article/details/80086183
今日推荐