HDU1532_Drainage Ditches_最大流模板题

来源:互联网 发布:淘宝代销怎么没有了 编辑:程序博客网 时间:2024/06/03 23:04

Drainage Ditches

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


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

给出 n 个点,部分点之间有通道,通道有最大流量。从 1 点到 m 点的最大流量。


最大流模板题。给出两种解法。这两种解法都是增广路的思想。


1.朴素的Ford-Fulkerson算法

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;struct edge{int to, cap, rev;};const int maxm = 220;const int inf  = 0x3fffffff;int n, m;vector<edge> G[maxm];bool usd[maxm];//添加边与反向边void Add(int from, int to, int cap){G[from].push_back((edge){to, cap, G[to].size()});G[to].push_back((edge){from, 0, G[from].size()-1});}//深搜增广int dfs(int v, int t, int f){//到达汇点if(v == t) return f;//访问标记usd[v] = true;//枚举这个点的边for(int i= 0; i< G[v].size(); i++){//注意引用edge &e = G[v][i];//终点没走过并且可以增广if(!usd[e.to] && e.cap > 0){//深搜求最短路int d = dfs(e.to, t, min(f, e.cap));//沿着这条路增广成功if(d > 0){//更新边和反向边e.cap -= d;G[e.to][e.rev].cap += d;//返回增加的流return d;}}}return 0;}//最大流求解函数int max_flow(int s, int t){//最大流int flow = 0;while(1){//初始化访问数组memset(usd, 0, sizeof usd);//下一步去1,汇点是m,当前最大流为inf//从源点到源点的初始化最大流是infint f = dfs(s, t, inf);//不存在增广路了,返回flowif(f == 0) return flow;//更新最大流flow += f;}}int main(){while(scanf("%d %d", &n, &m) != EOF){//初始化千万别忘了!for(int i= 1; i<= m; i++)G[i].clear();//建图for(int i= 0; i< n; i++){int s, e, d;scanf("%d %d %d", &s, &e, &d);Add(s, e, d);}cout << max_flow(1, m) << endl;}return 0;}


2.Dinic算法


#include<cstdio>#include<iostream>#include<cstring>#include<vector>#include<queue>using namespace std;struct edge{int to, cap, rev;};const int maxm = 220;const int inf  = 0x3fffffff;int n, m;vector<edge> G[maxm];int level[maxm];//分层图中的距离int iter [maxm];//当前弧,之前的弧都不能再增广了//添加边与反向边void Add(int from, int to, int cap){G[from].push_back((edge){to, cap, G[to].size()});G[to].push_back((edge){from, 0, G[from].size()-1});}//构造分层图void bfs(int s){memset(level, -1, sizeof level);level[s] = 0;queue<int> qu;qu.push(s);while(qu.size()){int v = qu.front();qu.pop();for(int i= 0; i< G[v].size(); i++){edge e = G[v][i];if(e.cap > 0 && level[e.to] < 0){level[e.to] = level[v] + 1;qu.push(e.to);}}}}int dfs(int v, int t, int f){if(v == t) return f;for(int &i = iter[v]; i < G[v].size(); i++){edge &e = G[v][i];if(e.cap > 0 && level[e.to] > level[v]){int d = dfs(e.to, t, min(f, e.cap));if(d > 0){e.cap -= d;G[e.to][e.rev].cap += d;return d;}}}return 0;}//最大流求解函数int max_flow(int s, int t){int flow = 0;while(1){//通过bfs构建分层图//寻找参与网络中最短的增广路bfs(s);//汇点不存在与分层图中,不再有增广路存在//返回最大流if(level[t] < 0) return flow;//初始化指针数组memset(iter, 0, sizeof iter);while(1){int f = dfs(s, t, inf);//f==0则当前分层图中不存在增广路//说明增广路变长了//退出循环重建分层图if(f == 0) break;//更新最大流flow += f;}}}int main(){while(scanf("%d %d", &n, &m) != EOF){//多数据的时候千万别忘了初始化for(int i= 1; i<= m; i++)G[i].clear();//建图for(int i= 0; i< n; i++){int s, e, d;scanf("%d %d %d", &s, &e, &d);Add(s, e, d);}cout << max_flow(1, m) << endl;}return 0;}


原创粉丝点击