B - Drainage Ditches POJ - 1273(网络流模板题)

 B - Drainage Ditches 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

 网络流模板。

下面是加反向边的解释

网上的PPT图片,以帮助理解代码中的加反向边部分的代码。增广路径是寻找一个可行的路径以增加总的流量。

第三步是关键点,很多博客理解3->2这一步为走后悔路。即可以理解为第一步中走2->3后悔了,2->3的流可以分d个流到2->4走,而分转走的d个流可以以走“后悔路3->2之前到3的d个流替代,那么整个过程从原点1到目标点5的流增加了d个流(现在我们可以很清晰地看到,走的“后悔路”经过的流最大可能是2->3的流,即2,所以可以在走过2->3的时候,为3->2设一条“后悔路”,即更新3->2的流即  gra[i^1].w+=tminl,反向边加流,相同的两个顶点的两个相反的流对应的边的末位一个是0,一个是1。这个可以在构造邻接表部分看出)

#include<cstdio>
#include<stack>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
#include<cmath>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
const int N=1000+5;
const int MOD = 1e5+ 7;
int n,m;
int head[N],cur[N],dep[222];
int ans;
struct node   //邻接表结构体
{
    int u,v,w;
    int next; 
} gra[N];
void ad(int u,int v,int w)  //邻接表
{
    gra[ans].next=head[u];    
    gra[ans].v=v;
    gra[ans].w=w;  //当前容量
    head[u]=ans++;
}
int bfs(){
queue<int>q;
memset(dep,0,sizeof(dep));
q.push(1);
dep[1]=1;
while(!q.empty()){
    int t=q.front();
    q.pop();
    for(int i=head[t];i!=-1;i=gra[i].next){
        if(!dep[gra[i].v]&&gra[i].w>0){
            dep[gra[i].v]=dep[t]+1;
            q.push(gra[i].v);
        }
    }
}
if(dep[m]==0)
    return 0;
return 1;
}
int dfs(int now,int minl){  //dfa寻找增广路径
    if(now==m)
        return minl;
for(int &i=cur[now];i!=-1;i=gra[i].next){
    if(dep[gra[i].v]==dep[now]+1&&gra[i].w>0){
        int tminl=dfs(gra[i].v,min(gra[i].w,minl));
        if(tminl>0){
            gra[i].w-=tminl;
            gra[i^1].w+=tminl;//反向边加流,用各位大佬的话说是为了可以后悔
            return tminl;
        }
    }
}
return 0;
}
int main()
{
    int u,v,w,sum;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        ans=0;
        sum=0;
        memset(head,-1,sizeof(head));
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            ad(u,v,w);
            ad(v,u,0);
        }
        while(bfs()){  
    /*bfs分层是为了不让dfs搜索越来越远离目标,多次bfs是因为反向边加流后层次有更新
    即可能某个边i^1作为某个正向边的反向边加了流,且该边原来的容量为0,没有在层次中,所以要再次更新层次
    */
           for(int i=1;i<=m;i++)
            cur[i]=head[i];
           while(int flow=dfs(1,inf))   //一次dfs只实现寻找一个增广路径的功能
            sum+=flow;
        }
        printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/clz16251102113/article/details/81254218