【USACO】草地排水
Drainage Ditches 草地排水 usaco 4.2.1
描述
在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。
农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。
根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。
格式
PROGRAM NAME:ditch
INPUT FORMAT:
(file ditch.in)
第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 FORMAT:
(file ditch.out)
输出一个整数,即排水的最大流量。
SAMPLE INPUT
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
SAMPLE OUTPUT
50
最大流裸题,被教练拖出来练了两次,一次用邻接矩阵,一次用链式前向星,具体看代码注释吧。
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
ifstream fin("ditch.in");
ofstream fout("ditch.out");
int dis[][]={};//邻接矩阵 存图
int far[]={};//距离源点的距离
int point=,bians=,ans=;
bool BFS();//寻找最短路
int find(int nw,int least);//寻找路径流通
int mn(int a,int b);//返回较小数的函数
int main(void)
{
fin>>bians>>point;
int a=,b=,pay=;
for(int i=;i<=bians;i++)
{
fin>>a>>b>>pay;
dis[a][b]+=pay;//构图
}
int liul=;
while(BFS())
{
while(liul=find(,0x7fffffff))//寻找可流通的路径【即所谓增广路】
{
ans+=liul;
}
}
fout<<ans;
return ;
} bool BFS()
{
int duil[]={},head=,tail=;
duil[head+]=;
memset(far,-,sizeof(far));
far[]=;
do
{
head++;
if(head==)head=;//循环队列处理
for(int i=;i<=point;i++)
{
if(dis[duil[head]][i]>&&far[i]<)
{
far[i]=far[duil[head]]+;
tail++;
if(tail==)tail=;//循环队列处理
duil[tail]=i;
}
}
}while(head!=tail);
if(far[point]>)return ;//如果找到到终点的路径,返回1
return ;//否则返回0
} int find(int nw,int least)//least代表当前可行的最大流量
{
if(nw==point)return least;
int run=,used=,syu=least;//used表示当前节点可流出的最大流量,syu代表当前可流出的流量
for(int i=;i<=point;i++)
{
if(dis[nw][i]>&&far[i]==far[nw]+)//如果当前点到第i点联通且当前点是路径的下一个点
{
run=find(i,mn(syu,dis[nw][i]));//递归寻找当前路径的最大流量
if(run!=)
{
dis[nw][i]-=run;//正弧减去最大流量
dis[i][nw]+=run;//反弧加上最大流量
syu-=run;//减去当前可流出流量
used+=run;//总流量加上当前增广路可流出流量
}
}
}
return used;
} int mn(int a,int b)
{
if(a>b)return b;
else return a;
}
链式前向星版
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
using namespace std;
ifstream fin("ditch.in");
ofstream fout("ditch.out");
struct ls
{
int nw;//当前标号
int to;//从nw到to有一条边
int rl;//当前可行容量
int nxt;//连接的下一条弧【注:根据链式前向星的规定,nxt指下一条弧在数组中的下标】
int fan;//反向弧的数组下标
};
ls qxq[];//链式前向星存储
int dis[]={};//当前节点距终点的距离
int tou[]={};//链式前向星的head数组
int point=,bians=,ans=,bian=;
bool BFS();//根据SPFA算法寻找最短路
int Dinic(int xz,int least);//进行水量输送与判断
int mn(int a,int b);//返回较小数的函数
void add(int fr,int to,int ll);//构建链式前向星
int main(void)
{
fin>>bians>>point;
memset(tou,-,sizeof(tou));
int a=,b=,c=;
for(int i=;i<=bians;i++)
{
fin>>a>>b>>c;
add(a,b,c);//构建链式前向星
}
int liul=;
while(BFS())//如果一次BFS没有寻找到可以到终点的路径,则算法结束。
{
while(liul=Dinic(,0x7fffffff))//一次BFS就不断寻找从起点到终点的路径并更改容量
{
ans+=liul;
}
}
fout<<ans;
return ;
} void add(int fr,int to,int ll)
{
qxq[bian].nw=fr;
qxq[bian].to=to;
qxq[bian].nxt=tou[fr];
tou[fr]=bian;
qxq[bian].rl=ll;
qxq[bian].fan=bian+;
bian++;//构建一条弧
qxq[bian].nw=to;
qxq[bian].to=fr;
qxq[bian].nxt=tou[to];
tou[to]=bian;
qxq[bian].rl=;
qxq[bian].fan=bian-;
bian++;//构建它的反向弧【注:这里我们不考虑从A到B有一条弧,B到A有另一条弧的情况】
//事实上,就算不考虑,算法对上述情况也可以正确运行
//至于原理何在,就交给读者自己思考(因为我也不知道)(划去)
} bool BFS()
{
int dl[]={},head=,tail=,bh=;
dl[head+]=;
memset(dis,-,sizeof(dis));
dis[]=;
do
{
head++;
if(head==)head=;
for(int i=tou[dl[head]];i>;i=qxq[i].nxt)
{
bh=qxq[i].to;
if(dis[bh]<&&qxq[i].rl>)
{
tail++;
if(tail==)tail=;
dl[tail]=bh;
dis[bh]=dis[dl[head]]+;
}
}
}while(head!=tail);
//看起来很像SPFA算法其实不是,因为这里一点出了队列就不可能再一次进入队列了
//所以准确的说,应该叫BFS更加贴切
if(dis[point]<=)return ;//如果没有找到路径就返回0
return ;
} int Dinic(int xz,int least)//least代表当前可行流量
{
if(xz==point)return least;//如果当前点已经是终点就返回当前流量
int run=,bh=,used=,syu=least;//同邻接矩阵版注释
for(int i=tou[xz];i>;i=qxq[i].nxt)
{
bh=qxq[i].to;//枚举下一个点
if(dis[bh]==dis[xz]+)//如果当前点是最短路径的下一个点
{
run=Dinic(bh,mn(syu,qxq[i].rl));//递归计算可行流量
if(run!=)
{
qxq[i].rl-=run;//正弧减去可行流量
qxq[qxq[i].fan].rl+=run;//反弧加上可行流量
syu-=run;//当前可用流量减去流出流量
used+=run;//当前流出总流量加上流出流量
}
}
}
return used;
} int mn(int a,int b)
{
if(b>a)return a;
else return b;
}
【USACO】草地排水的更多相关文章
- 题解 【USACO 4.2.1】草地排水
[USACO 4.2.1]草地排水 Description 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫 ...
- AC日记——草地排水 codevs 1993
1993 草地排水 USACO 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 在农夫约翰的农场上,每 ...
- - > 网络流(【最大流】草地排水模板题)
1993 草地排水 USACO 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 在农夫约翰的农场上,每 ...
- codevs1993 草地排水(最大流)
1993 草地排水 USACO 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bes ...
- 【codevs1993】草地排水 最大流
[codevs1993]草地排水 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段 ...
- [网络流]Drainage Ditches(草地排水)
Drainage Ditches(草地排水) 题目描述 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰 ...
- Codevs 1993 草地排水
1993 草地排水 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地 ...
- codevs 1993草地排水
1993 草地排水
- 草地排水 洛谷P2740 最大流 入门题目
草地排水 洛谷P2740 最大流入门题目 题意 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一 ...
随机推荐
- Vi编辑器入门
Vi编辑器入门 vi编辑器是所有Unix及Linux系统下标准的编辑器,类似于windows上的记事本! 1.vi的基本概念 基本上vi可以分为三种状态,分别是命令模式(command mode ...
- 关于grub的那些事(三)
接着第二篇的研究,继续分析/etc/grub.d/10_linux. #! /bin/sh set -e prefix="/usr" exec_prefix="${pre ...
- [RM 状态机详解4] RMNode状态机详解
摘要 RMNode状态机是ResourceManager的四个状态机(RMApp,RMAppAttempt,RMContainer,RMNode)中最简单的一个,状态机如图1所示.RMNode是Res ...
- (coco2d-x初学)xcode5.0安装 cocos2d-x2.2.0
cocos2d-x 2.0版本之后不再支持xcode模板安装. 下面介绍一下创建步骤:我下载的是cocos2d-x2.2.0版本 1.下载Cocos2d-x的地址点击打开链接 2.解压缩压缩包.打开终 ...
- Java快速开发工具 WebBuilder 6.8发布
WebBuilder是一款开源的可视化Java Web应用开发和运行平台: 基于浏览器的集成开发环境,可视化和智能化的设计,能轻松完成常规应用和面向手机的移动应用开发: 高效.稳定和可扩展的特点,适合 ...
- 史上最全条件编译解析 #ifdef #ifndef #undef #else #endif
C语言和C++语言程序中广泛存在着#ifdef或#ifndef等条件编译语句,本篇就系统介绍下他们的用法. 这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分 ...
- 百万行mysql数据库优化和10G大文件上传方案
百万行mysql数据库优化和10G大文件上传方案 最近这几天正在忙这个优化的方案,一直没时间耍,忙碌了一段时间终于还是拿下了这个项目?项目中不要每次都把程序上的问题,让mysql数据库来承担,它只是个 ...
- 【转载】Servlet Filter(过滤器)、Filter是如何实现拦截的、Filter开发入门
Servlet Filter(过滤器).Filter是如何实现拦截的.Filter开发入门 Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过F ...
- USACO 4.1 Beef McNuggets
Beef McNuggetsHubert Chen Farmer Brown's cows are up in arms, having heard that McDonalds is conside ...
- C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托
现在有一个按钮btn1,要动态创建出一个btn2,需要btn2点击时调用btn1的点击. 在delphi中这种操作很简单:btn2.onClick:=btn1.onClick,因为onClick就是个 ...