HDU 1532 Drainage Ditches (最大流模板)

来源:互联网 发布:淘宝电器以旧换新 编辑:程序博客网 时间:2024/05/16 12:00

Drainage Ditches

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15001    Accepted Submission(s): 7124


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 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.
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.
 

Input
The input includes several cases. For each case, the first line contains 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. Each of the following 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.
 

Output
For each case, output a single integer, the maximum rate at which water may emptied from the pond.
 

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

Sample Output
50
 

Source
USACO 93
 

思路:这是最大流模板,用的是Ford-Fulkerson算法,大概意思就是一副有向图,有一个源点,一个汇点,每条边都有最大承载容量,源点可以发出任意大小的流量,求汇点接收流量的最大值。源点发出 的流量一定等于汇点接收的流量( f(s) = f(t) ),为了求解方便,将有向图改成无向图,单向边都加上另一个方向的边,并且都求得该方向的容量,反向边的流量其实相当于将正向边的流量推回发出流量的节点并用于别的路径。有了双向边之后,无向图就建立成功了,要进行dfs,每次dfs都是寻找增广路,就是找到一条由全都满足容量大于0(正向是f(e) < c(e),反向则是f(e)>0)的边的路,并根据最后的边来确定这条增广路能增加多少流量。整个过程就是不停的寻找增广路增加流量,直到找不到增广路,就求出了最大流量。

代码如下:

#include<cstdio>#include<iostream>#include<cstring>#include<vector>#include<cmath>#include<algorithm>#define MAXV 205#define INF 0x3f3f3f3f using namespace std;struct edge{int to, cap, rev;//边另一边的顶点,该边该方向的容量,反向边在数组g[to]的下标i };vector<edge> g[MAXV];bool used[MAXV];int m, n;void add_edge(int from, int to, int cap){g[from].push_back((edge){to, cap, g[to].size()});//注意这里的size不用减一g[to].push_back((edge){from, 0, g[from].size() - 1});//因为下面即将添加 }int dfs(int s, int t, int f){if(s == t)return f;//如果已经到终点了,则返回到达终点的流量。 used[s] = 1;for(int i = 0; i < g[s].size(); i++){edge &e = g[s][i];//引用,类似于指针,改变了e就改变了g[s][i] if(!used[e.to] && e.cap > 0)//若该边访问过且该边该方向容量有余 {int d = dfs(e.to, t, min(f,e.cap));//递归,流量取该边容量和该点拥有流量的最小值 if(d > 0){e.cap -= d;//正向边容量减去d g[e.to][e.rev].cap += d;//反向边容量加上d,相当于可以推回节点的流量增加了d return d;}}}return 0;}int max_flow(int s, int t)//求s到t的最大流 {int flow = 0;while(1){memset(used, 0, sizeof(used));//每次dfs都要初始化 int f = dfs(s, t, INF);//源点的流量为无穷大 cout<<f<<endl; if(f == 0) return flow;//如果无法找到增广路了,就说明flow已经为最大流 flow += f;}}int main(){int i, j, u, v, c;while(scanf("%d%d", &m, &n) != EOF){for(i = 1; i <= n; i++)//初始化,清空邻接表 {g[i].clear();}for(i = 1; i <= m; i++){scanf("%d%d%d", &u, &v, &c);add_edge(u, v, c);//双向添加边 }printf("%d\n",max_flow(1, n));}return 0;} 

        

0 0
原创粉丝点击