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】草地排水的更多相关文章

  1. 题解 【USACO 4.2.1】草地排水

    [USACO 4.2.1]草地排水 Description 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫 ...

  2. AC日记——草地排水 codevs 1993

    1993 草地排水 USACO  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在农夫约翰的农场上,每 ...

  3. - > 网络流(【最大流】草地排水模板题)

    1993 草地排水 USACO  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在农夫约翰的农场上,每 ...

  4. codevs1993 草地排水(最大流)

    1993 草地排水 USACO  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在农夫约翰的农场上,每逢下雨,Bes ...

  5. 【codevs1993】草地排水 最大流

    [codevs1993]草地排水 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段 ...

  6. [网络流]Drainage Ditches(草地排水)

    Drainage Ditches(草地排水) 题目描述 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰 ...

  7. Codevs 1993 草地排水

    1993 草地排水 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地 ...

  8. codevs 1993草地排水

    1993 草地排水

  9. 草地排水 洛谷P2740 最大流 入门题目

    草地排水 洛谷P2740 最大流入门题目 题意 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一 ...

随机推荐

  1. 通过Thrift访问HDFS分布式文件系统的性能瓶颈分析

    通过Thrift访问HDFS分布式文件系统的性能瓶颈分析 引言 Hadoop提供的HDFS布式文件存储系统,提供了基于thrift的客户端访问支持,但是因为Thrift自身的访问特点,在高并发的访问情 ...

  2. SubSonic3.0配置及使用

    SubSonic3.0配置及使用 SubSonic is A Super High-fidelity Batman Utility Belt that works up your Data Acces ...

  3. hdu 4277 USACO ORZ (dfs暴搜+hash)

    题目大意:有N个木棒,相互组合拼接,能组成多少种不同的三角形. 思路:假设c>=b>=a 然后枚举C,在C的dfs里嵌套枚举B的DFS. #include <iostream> ...

  4. 模块化与MVC

    [javascript激增的思考02]模块化与MVC 前言 之前我们遇到了这么一个项目,也就是我们昨天提到的,有很多的小窗口的,昨天说的太抽象了,今天我们再来理一理什么是小窗口(后面点说下),当时由于 ...

  5. for惠普2013实习生

    似乎快两个月了,惠普招实习生的时间好像确实有点久. 记得是从五月中旬的时候,惠普来学校招实习生的.因为没能够去腾讯,能拿到惠普的实习生offer也是我所愿了. 记得宣讲的那天,兴冲冲的过去了,惠普的一 ...

  6. Execl导入问题之文本转换

    前些天在基础数据的导入过程中,遇到了这样一个问题:数据明明存在,可是就是不识别!给出的错误提示是:该数据对应的外键不存在! 我找出其中的一条数据,在外键表中查询是存在的!问题出在哪里了呢? 从exec ...

  7. android jni ndk 视频分享

    链接如下:http://download.csdn.net/detail/jltxgcy/5667327.

  8. jq模糊匹配

    jq是一般程序员在前台开发的时候都会使用的技术,其中模糊匹配查询在动态添加标签的时候经常用到,这里我写出我经常用到的几个模糊匹配的方法.其中有:^(前缀).$(后缀).*(包含)例如有这样一段代码: ...

  9. HTTP could not register URL http://+:86/. 设置VS默认以管理员权限打开

      在使用visual studio 2013启动self host webapi时候碰到下面的错误: 详细错误信息如下: HTTP could not register URL http://+:8 ...

  10. java switch 优化

    关键字 switch 语句用于多条件判断,switch 语句的功能类似于 if-else 语句,两者的性能差不多.但是 switch 语句有性能提升空间.清单 16 所示代码演示了 Switch 与 ...