C++——【USACO 4.2.1】——Drainage Ditches

来源:互联网 发布:武汉软件新城花城汇 编辑:程序博客网 时间:2024/06/07 01:21

Drainage Ditches
Hal Burch

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. Note however, that there can be more than one ditch between two intersections.

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.

PROGRAM NAME: ditch

INPUT FORMAT

Line 1: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.Line 2..N+1:Each of 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.

SAMPLE INPUT (file ditch.in)

5 41 2 401 4 202 4 202 3 303 4 10

OUTPUT FORMAT

One line with a single integer, the maximum rate at which water may emptied from the pond.

SAMPLE OUTPUT (file ditch.out)

50


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

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

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

输入格式

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

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

输出格式

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

样例数据 1

输入

5 4 
1 2 40 
1 4 20 
2 4 20 
2 3 30 
3 4 10

输出

50

最大流。

注意:建边之前 size 初始化为1,所以边从2开始编号,所以求最大流的时候(find 函数),假设正向边是 i ,则其反向边就是 i^1 。(异或)

如果从 size 从 1 开始建边,则反向边为:i+i&1?1:-1。 



/*ID : mcdonne1LANG : C++TASK : ditch*/#include<cstdio>#include<queue>#include<cstring>using namespace std;struct node{int next,v,c;}e[500];int n,m,x,y,z,cnt=1,ans,flow;int d[300],first[300];bool q[300];inline int read(){int i=0;char c=getchar();while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') i=(i<<3)+(i<<1)+c-48,c=getchar();return i;}inline void add(int x,int y,int z){e[++cnt].v=y;e[cnt].c=z;e[cnt].next=first[x];first[x]=cnt;e[++cnt].v=x;e[cnt].c=0;e[cnt].next=first[y];first[y]=cnt;}inline bool build(){queue <int> __q;memset(d,-1,sizeof(d));__q.push(1);q[1]=true;d[1]=0;while(!__q.empty()){int x=__q.front();__q.pop();for(int i=first[x];i!=-1;i=e[i].next)if(e[i].c&&d[e[i].v]==-1){d[e[i].v]=d[x]+1;__q.push(e[i].v);q[e[i].v]=true;if(e[i].v==m) return true;}}return false;}int find(int now,int flow){if(now==m) return flow;int ret,y,w=0;for(int i=first[now];i!=-1&&w<flow;i=e[i].next){y=e[i].v;if(e[i].c&&d[y]==d[now]+1&&(ret=find(y,min(flow-w,e[i].c)))){e[i].c-=ret;e[i^1].c+=ret;w+=ret;}}if(!w) d[now]=-1;return w;}int main(){freopen("ditch.in","r",stdin);freopen("ditch.out","w",stdout);memset(first,-1,sizeof(first));n=read();m=read();for(int i=1;i<=n;++i){x=read();y=read();z=read();add(x,y,z);}while(build())while(true){flow=find(1,1<<30);if(!flow) break;ans+=flow;}printf("%d\n",ans);return 0;}



原创粉丝点击