pid=1532">Drainage Ditches

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 8574    Accepted Submission(s): 3991

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 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
 
Sample Output
50

题目大意:

就是因为下大雨的时候约翰的农场就会被雨水给淹没。无奈下约翰不得不修建水沟,并且是网络水沟,并且聪明的约翰还控制了水的流速,本题就是让你求出最大流速,无疑要运用到求最大流了。

题中m为水沟数。n为水沟的顶点,接下来Si,Ei,Ci各自是水沟的起点,终点以及其容量。求源点1到终点n的最大流速。

注意重边

</pre></p><pre name="code" class="cpp">
EdmondsKarp算法写的:
邻接矩阵:
</pre><pre name="code" class="cpp">
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f using namespace std; const int M = 1000 + 50;
int n, m;
int r[M][M];
int pre[M];// 记录结点i的前向结点为pre[i]
bool vist[M];// 记录结点i是否已訪问 bool BFS(int s, int t) //推断是否存在增广路
{
queue<int>que;
memset(pre, 0, sizeof(pre));
memset(vist, false, sizeof(vist));
pre[s] = s;
vist[s] = true;
que.push(s);
int p;
while( !que.empty() )
{
p = que.front();
que.pop();
for(int i=1; i<=n; i++)
{
if(r[p][i]>0 && !vist[i])
{
pre[i]=p;
vist[i]=true;
if( i==t )
return true;
que.push(i);
}
}
}
return false;
} int EK(int s, int t)
{
int maxflow = 0;
while( BFS(s, t) )
{
int d = INF;
// 若有增广路径,则找出最小的delta
for(int i=t; i!=s; i=pre[i])
d = min(d, r[ pre[i] ][i]);
// 这里是反向边
for(int i=t; i!=s; i=pre[i])
{
r[ pre[i] ][i] -= d;//方向边
r[i][ pre[i] ] += d;//方向边
}
maxflow += d;
}
return maxflow;
} int main()
{
while(cin>>m>>n)
{
memset(r, 0, sizeof(r));
for(int i=0; i<m; i++)
{
int from, to, rap;
scanf("%d%d%d", &from, &to, &rap);
r[from][to] += rap;
}
cout<<EK(1, n)<<endl;
}
return 0;
}

邻接表(紫书上的模板):

#include<cstdio>

#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue> using namespace std; #define INF 0x3f3f3f3f;
const int MAXN = 1000 + 50; struct Edge
{
int from, to, cap, flow;
Edge (int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {}
}; struct EdmondsKarp
{
int n, m;
vector<Edge> edges;
vector<int> G[MAXN];
int a[MAXN];
int p[MAXN]; void init(int n)
{
for(int i=0; i<n; i++)
G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap)
{
edges.push_back( Edge(from, to, cap, 0) );
edges.push_back( Edge(to, from, 0, 0) );
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
} int Maxflow(int s, int t)
{
int flow = 0;
for( ; ; )
{
memset(a, 0, sizeof(a));
queue<int> Q;
Q.push(s);
a[s]=INF;
while( !Q.empty() )
{
int x = Q.front();
Q.pop();
for(int i=0; i<G[x].size(); i++)
{
Edge& e = edges[ G[x][i] ];
if( !a[e.to] && e.cap > e.flow )
{
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap-e.flow);
Q.push(e.to);
}
}
if( a[t] ) break;
}
if( ! a[t] ) break;
for(int u=t; u!=s; u=edges[ p[u] ].from )
{
edges[ p[u] ].flow += a[t];
edges[ p[u]^1 ].flow -= a[t];
}
flow += a[t];
}
return flow;
} }; int main()
{
EdmondsKarp T;
int n, m;
while(scanf("%d%d", &m, &n) !=EOF)
{
T.init(n+1);
for(int i=0; i<m; i++)
{
int a1, a2, a3;
scanf("%d%d%d", &a1, &a2, &a3);
T.AddEdge(a1, a2, a3);
}
printf("%d\n", T.Maxflow(1, n));
} return 0;
}

Dinic算法:

#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 205
#define INF 1000000000
using namespace std;
struct Edge {
int from, to, cap, flow;
}; struct Dinic {
int n, m, s, t;
vector<Edge> edges; //边表.edges[e]和edges[e^1]互为反向弧
vector<int> G[MAXN]; //邻接表。G[i][j]表示结点i的第j条边在e数组中的序号
bool vis[MAXN]; //BFS使用
int d[MAXN]; //从起点到i的距离
int cur[MAXN]; //当前弧指针 void ClearAll(int n) {
for (int i = 0; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap) {
edges.push_back((Edge) {from, to, cap, 0});
edges.push_back((Edge) {to, from, 0, 0});
m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
} bool BFS() {//使用BFS计算出每个点在残量网络中到t的最短距离d.
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = 1;
d[s] = 0;
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap > e.flow) { //仅仅考虑残量网络中的弧
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x, int a) {//使用DFS从S出发,沿着d值严格递减的顺序进行多路增广。
if (x == t || a == 0) return a;
int flow = 0, f;
for (int& i = cur[x]; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
e.flow += f;
edges[G[x][i] ^ 1].flow -= f;
flow += f;
a -= f;
if (a == 0) break;
}
}
return flow;
} int Maxflow(int s, int t) {
this->s = s; this->t = t;
int flow = 0;
while (BFS()) {
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
} };
Dinic g;
int main()
{
int n, m, i, a, b, c;
while (~scanf("%d%d", &m, &n)) {
g.ClearAll(n + 1);
for (i = 0; i < m; i++) {
scanf("%d%d%d", &a, &b, &c);
g.AddEdge(a, b, c);
}
int flow = g.Maxflow(1, n);
printf("%d\n", flow);
}
return 0;
}

HDU 1532||POJ1273:Drainage Ditches(最大流)的更多相关文章

  1. 【47.63%】【hdu 1532】Drainage Ditches

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

  2. poj-1273 Drainage Ditches(最大流基础题)

    题目链接: Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 67475   Accepted ...

  3. POJ-1273 Drainage Ditches 最大流Dinic

    Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65146 Accepted: 25112 De ...

  4. POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)

    http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...

  5. poj1273 Drainage Ditches (最大流板子

    网络流一直没学,来学一波网络流. https://vjudge.net/problem/POJ-1273 题意:给定点数,边数,源点,汇点,每条边容量,求最大流. 解法:EK或dinic. EK:每次 ...

  6. [poj1273]Drainage Ditches(最大流)

    解题关键:最大流裸题 #include<cstdio> #include<cstring> #include<algorithm> #include<cstd ...

  7. poj1273 Drainage Ditches Dinic最大流

    Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 76000   Accepted: 2953 ...

  8. Poj 1273 Drainage Ditches(最大流 Edmonds-Karp )

    题目链接:poj1273 Drainage Ditches 呜呜,今天自学网络流,看了EK算法,学的晕晕的,留个简单模板题来作纪念... #include<cstdio> #include ...

  9. POJ 1273 || HDU 1532 Drainage Ditches (最大流模型)

    Drainage DitchesHal Burch Time Limit 1000 ms Memory Limit 65536 kb description Every time it rains o ...

随机推荐

  1. 紫书 例题8-1 UVa 120(构造法)

    #include<cstdio> #include<iostream> #include<sstream> #include<algorithm> #d ...

  2. cogs 2752. [济南集训 2017] 数列运算

    2752. [济南集训 2017] 数列运算 ★★☆   输入文件:sequenceQBXT.in   输出文件:sequenceQBXT.out   简单对比时间限制:1 s   内存限制:512 ...

  3. Windows下面使用curl

    Windows下面使用curl 学习了:https://www.cnblogs.com/xing901022/p/4652624.html 下载地址:https://curl.haxx.se/down ...

  4. 基于One-Class的矩阵分解方法

    在矩阵分解中. 有类问题比較常见,即矩阵的元素仅仅有0和1. 相应实际应用中的场景是:用户对新闻的点击情况,对某些物品的购买情况等. 基于graphchi里面的矩阵分解结果不太理想.调研了下相关的文献 ...

  5. 1.RunLoop是什么?

    1.Run loops是线程相关的的基础框架的一部分. 一个run loop就是一个事件处理的循环.用来不停的调度工作以及处理输入事件.使用run loop的目的是让你的线程在有工作的时候忙于工作.而 ...

  6. 在Visual Studio Code中使用C#以及.net core

    Working with C# Using .NET Core in Visual Studio Code Note: VS Code does not support debugging appli ...

  7. composer是什么

    composer是什么 Composer 是 PHP5.3以上 的一个依赖管理工具.它允许你声明项目所依赖的代码库,它会在你的项目中为你安装他们.Composer 不是一个包管理器.是的,它涉及 &q ...

  8. pgsql数据库备份还原记

    今天又搞了一个pgsql 的备份还原,差一点没有成功,以前总是想当然的用,没认真想背后的东西,也没对过程中的疑问做记录,所以后面也没什么印象,常见常新,这次既然又遇到就总结一下. 之前操作pgsql数 ...

  9. luogu 1351 联合权值

    联合权值 题目大意 给你一个图,有\(n-1\)条边,距离均为\(1\),每距离为\(2\)的两个点的联合权值为\(W_u \times W_v\),求联合权值的最大值和联合权值总和. solutio ...

  10. 忽略PyCharm4中特定的警告提示信息

    有一种简单的方式忽略PyCharm4中的警告,光标放在下划线上,a. 等灯泡出现,点击灯泡或者b. 按下Alt和Enter键,选择'Ignore errors like this'. 或者,在设置里更 ...