[usaco]4.2.1 最大流问题Drainage Ditches

 

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 4
1 2 40
1 4 20
2 4 20
2 3 30
3 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:找到一个最大流路径,
2:求出其中最小的边值w;
3:把流路径上的每一条边减去w,并反向增加一条w的边。
4:重复1-3,直到找不到这样的一条路径为止。

找最大流路径的算法使用变形的dijeskal算法。

/*
ID:yunleis2
PROG:ditch
LANG:C++
*/

#include<iostream>
#include<fstream>

using namespace std;

const int MAXN=201;
const int MAXM=201;
int N;
int M;
int metri[MAXM][MAXM];
int prevs[MAXM];
int length[MAXM];
bool visited[MAXM];
int main()
{
	fstream fin("ditch.in",ios::in);
	fin>>N>>M;
	for(int i=0;i<N;i++){
		int a,b,c;
		fin>>a>>b;
		fin>>c;
		metri[a][b]+=c;
	}
	int total=0;
	int flag=true;
	while(flag){
		//disjeskal to find a max flow;
		for(int i=1;i<=M;i++){
			length[i]=metri[1][i];//-metri[i][1];
			prevs[i]=1;
			visited[i]=false;
		}
		prevs[1]=0;
		visited[1]=true;
		while(true){
			int ptr=1;
			int maxflow=0;
			for(int i=1;i<=M;i++){
				if(!visited[i]&&length[i]>maxflow){
					maxflow=length[i];
					ptr=i;
				}
			}
			if(maxflow<=0)
			{
				flag=false;
				break;
			}
			visited[ptr]=true;
			if(ptr==M){
				int ptr1=ptr;
				int minflow=1000000;
				while(ptr1!=1){
					if((metri[prevs[ptr1]][ptr1]/*-metri[ptr1][prevs[ptr1]]*/)<minflow)
						minflow=metri[prevs[ptr1]][ptr1];//-metri[ptr1][prevs[ptr1]];
					ptr1=prevs[ptr1];
				}
				ptr1=ptr;
				while(ptr1!=1){
					metri[prevs[ptr1]][ptr1]-=minflow;
					metri[ptr1][prevs[ptr1]]+=minflow;
					ptr1=prevs[ptr1];
				}
				total+=minflow;
				break;
			}
			for(int i=1;i<=M;i++){
				if(!visited[i]&&(metri[ptr][i]/*-metri[i][ptr]*/)>length[i]){
					length[i]=metri[ptr][i];//-metri[i][ptr];
					prevs[i]=ptr;
				}
			}

		}
	}
	fstream fout("ditch.out",ios::out);
	fout<<total<<endl;
	//system("pause");

} 
 

USER: Ma yunlei [yunleis2]
TASK: ditch
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 3184 KB]
   Test 2: TEST OK [0.000 secs, 3184 KB]
   Test 3: TEST OK [0.000 secs, 3184 KB]
   Test 4: TEST OK [0.000 secs, 3184 KB]
   Test 5: TEST OK [0.000 secs, 3184 KB]
   Test 6: TEST OK [0.000 secs, 3184 KB]
   Test 7: TEST OK [0.000 secs, 3184 KB]
   Test 8: TEST OK [0.000 secs, 3184 KB]
   Test 9: TEST OK [0.000 secs, 3184 KB]
   Test 10: TEST OK [0.000 secs, 3184 KB]
   Test 11: TEST OK [0.000 secs, 3184 KB]
   Test 12: TEST OK [0.000 secs, 3184 KB]

All tests OK.
YOUR PROGRAM ('ditch') WORKED FIRST TIME!  That's fantastic
-- and a rare thing.  Please accept these special automated
congratulations.

 

时间: 2024-11-27 23:24:50

[usaco]4.2.1 最大流问题Drainage Ditches的相关文章

poj 1273 Drainage Ditches

click here ~~ Drainage Ditches Description 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 Jo

POJ题目分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

poj分类

初期: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和广度优先遍历.      (2)最短路径算法(dijkstra,bellman-ford

ACM练级

一般要做到50行以内的程序不用调试.100行以内的二分钟内调试成功.acm主要是考算法的 ,主要时间是花在思考算法上,不是花在写程序与debug上.  下面给个计划你练练: 第一阶段: 练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打 出来.  1.最短路(Floyd.Dijstra,BellmanFord)  2.最小生成树(先写个prim,kruscal要用并查集,不好写)  3.大数(

hduoj题目分类

基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058.1061.1070.1076.1089.1090.1091.1092.1093.1094.1095.1096.1097.1098.1106.1108.1157.1163.1164.1170.1194.1196.1197.1201.1202.1205.1219.1234.1235.1236.1248.1

最大流-hdoj-1532

hdoj-1532-Drainage Ditches Problem Description 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 a while and  takes quite along time to regrow.  Thus, F

图的匹配问题与最大流问题(五)计算二分图的最大匹配

二分图的最大匹配问题第一篇已经说过,下面看看百度百科给的一些解释: 给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数.最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配.选择这样的边数最大的子集称为图的最大匹配问题. 如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配

图的匹配问题与最大流问题(四)计算图的边连通度和点连通度

最近有点忙,好久没跟进了,有兴趣的朋友可以先熟悉下前三篇文章内容,(一)讲述了基础概念:(二)介绍了最大流算法的实现原理以及证明:(三)用Java语言予以了实现,欢迎大家批评指正. 回到正题,首先介绍下什么是图的边连通度和点连通度.一般来说,点连通度是指对应一个图G,对于所有点集U属于V(G),也就是V(G)的子集中,使得G-U要么是一个非连通图,要么就是一个平凡图(即仅包含一个独立点的图),其中最小的集合U的大小就是图G的点连通度,有时候也直接称为图的连通度.通俗点说,就是一个图G最少要去掉多

图的匹配问题与最大流问题(二) 最大流问题Ford-Fulkerson方法

本篇承接上一篇文章,主要讲解最大流问题的Ford-Fulkerson解法.可是说这是一种方法,而不是算法,因为它包含具有不同运行时间的几种实现.该方法依赖于三种重要思想:残留网络,增广路径和割.本文将会详细介绍这些内容,下一篇文章我们提供一种该方法的Java实现. 在介绍着三种概念之前,我们先简单介绍下Ford-Fulkerson方法的基本思想.首先需要了解的是Ford-Fulkerson是一种迭代的方法.开始时,对所有的u,v属于V,f(u,v)=0(这里f(u,v)代表u到v的边当前流量),