zoukankan      html  css  js  c++  java
  • 最大流 [USACO4.2]草地排水Drainage Ditches

    Background

    在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。

    Description

    农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。

    根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。

    Input

    第1行: 两个用空格分开的整数N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。

    第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是这条排水沟的最大容量。

    Output

    输出一个整数,即排水的最大流量。

    裸的网络流,答案即为从(1)(m)的最大流。

    注意看清我的输入,稳稳(AC)

    代码

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue> 
    #include<iostream>
    #define clear(a,b) memset(a,b,sizeof a)
    #define R register
    
    using namespace std;
    
    const int gz=1500000+10;
    
    inline void in(R int &x)
    {
    	R int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    
    int head[gz],depth[gz],tot,n,m,cur[gz],s,t;
    
    struct cod{int u,v,w;}edge[gz];
    
    inline void add(R int x,R int y,R int z)
    {
        edge[++tot].u=head[x];
        edge[tot].v=y;
        edge[tot].w=z;
        head[x]=tot;
    }
    
    inline bool bfs()
    {
    	clear(depth,0);queue<int>q;
    	depth[s]=1;q.push(s);
    	for(R int i=1;i<=n;i++)cur[i]=head[i];
    	while(!q.empty())
    	{
    		R int u=q.front();q.pop();
    		for(R int i=head[u];i!=-1;i=edge[i].u)
    		{
    			if(depth[edge[i].v]==0 and edge[i].w>0)
    			{
    				depth[edge[i].v]=depth[u]+1;
    				q.push(edge[i].v);
    			}
    		}
    	}
    	return depth[t];
    }
    
    inline int dfs(R int u,R int dist)
    {
    	if(u==t or !dist)return dist;
    	R int di=0,f;
    	for(R int i=cur[u];i!=-1;i=edge[i].u)
    	{
    		cur[u]=i;
    		if(depth[edge[i].v]==depth[u]+1 and (f=dfs(edge[i].v,min(edge[i].w,dist))))
    		{
    			di+=f;dist-=f;
    			edge[i].w-=f;edge[i^1].w+=f;
    			if(dist==0)break;
    		}
    	}
    	return di;
    }
    
    inline int dinic()
    {
    	R int ans=0;
    	while(bfs())ans+=dfs(s,214748364);
    	return ans;
    }
    
    int main()
    {
    	in(m),in(n);s=1,t=n;
    	clear(head,-1);tot=-1;
    	for(R int i=1,x,y,z;i<=m;i++)
    	{
    		in(x),in(y),in(z);
    		add(x,y,z);add(y,x,0);
    	}
    	printf("%d
    ",dinic());
    }
    
  • 相关阅读:
    【数据结构】线段树(Segment Tree)
    c++基础--数字读入及优化
    转:async异步、thread多线程
    走进 Akka.NET
    基于 Docker 的 DevOps 搭建
    (翻译)与.NET容器映像保持同步
    (翻译)使用 AppCenter 持续输出导出到 Application Insights
    (翻译)Xamarin.Essentials 最新预览版的更多跨平台 API
    (翻译)在 Xamarin 应用中使用 MongoDB
    (翻译)一起使用 .NET 和 Docker——DockerCon 2018 更新
  • 原文地址:https://www.cnblogs.com/-guz/p/9974724.html
Copyright © 2011-2022 走看看