【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 最大流入门题目 题意 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一 ...
随机推荐
- Arduino VS. Raspberry Pi VS. Beaglebone Black
The Arduino is a small Atmel-based microcontroller development board easily integrated into many dif ...
- Linux下搭建Nginx+MySQL+PHP
在CentOS6.3下实践通过. 1.关闭防火墙 [root@CentOS ~]# chkconfig iptables off 2.关闭selinux vi /etc/sysconfig/selin ...
- ASP.NET Web API 2.0新特性:Attribute Routing1
ASP.NET Web API 2.0新特性:Attribute Routing[上篇] 对于一个针对ASP.NET Web API的调用请求来说,请求的URL和对应的HTTP方法的组合最终决定了目标 ...
- 尽量不用char*作为hash_map的key
引子: 同事前几天用hash_map时发现一些问题.当时的场景是有一些字符串char*,要去对应某种类型的对象.同事的做法是: 尝试用char*作为key进行hash.编译通过,但运行时不正常,ins ...
- 编译linux内核时出错
在编译linux内核的时候使用make menuconfig 可能出现下面的错误 *** Unable to find the ncurses libraries or the*** required ...
- txt文件保存问题
今天终于解决了文件的保存问题,之前删除文件,再保存,发现删除的内容还是在文件中. 这是因为保存内容时,是将数组内容一行一行覆盖原来的内容,没有覆盖到的还是保存在文件内. 我用的是CFile类 所以直接 ...
- WPF界面设计
WPF仿360卫士9.0界面设计 Chrome插件——一键保存网页为PDF1.0 http://www.cnblogs.com/bdstjk/p/3163723.html 仿照网上的一个代码写的, ...
- Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
- jvm工具
jvm工具 知识,经验是基础,数据是依据,工具是运营知识处理数据的手段 数据:运行日志.异常堆栈.GC日志.线程快照.堆转存储快照 JPS:虚拟机进程状况工具 jvm process status t ...
- 使用div模拟textarea,实现文本输入框高度自适应(附:js控制textarea实现文本输入框高度自适应)
一.使用textarea标签进行多行文本的输入有很多限制,比如不能实现高度自适应,会出现难看的滚动条等问题. HTML5中添加了一个新属性contenteditable,该属性可以让input,tex ...