草地排水 洛谷P2740 最大流入门题目

题意

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

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

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

输入格式

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

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

输出格式

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

  1. //下面是样例输入
  2. 5 4
  3. 1 2 40
  4. 1 4 20
  5. 2 4 20
  6. 2 3 30
  7. 3 4 10
  8. //样例输出
  9. 50

解题思路

这个是我学习最大流算法时,看到有博客说这个是个入门题目,确实很基础。

具体的最大流讲解就不说了,推荐看这个博客网络流入门之最大流算法(增广路算法 由Ford-Fulkerson到Edmonds-Karp到dinic) 包看懂,确实讲的不错,尤其是他的代码实现是那种最基本的形式。

下面的代码两个版本,一个是基于他的进行了更改,另一个是看的《算法竞赛入门经典(第二版)》368页的实现代码,更加的高级吧。

代码实现

  1. //我的EK写法。。。建议邻接矩阵
  2. //题目:洛谷p2740 草地排水
  3. #include<bits/stdc++.h>
  4. using namespace std;
  5. const int inf=0x3f3f3f3f;
  6. int m,n,cap[205][205],pre[205],flow[205][205];
  7. int vis[205];
  8. bool bfs(int s,int t)
  9. {
  10. // memset(pre,-1,sizeof(pre));
  11. memset(vis,0,sizeof(vis));
  12. queue<int> q;
  13. q.push(s);
  14. vis[s]=inf;
  15. while(!q.empty())
  16. {
  17. int now=q.front();
  18. q.pop();
  19. for(int i=1;i<=n;i++)
  20. {
  21. //这里vis不仅代表标记,还记录了到这个结点可以减去的最小流量值
  22. //这样就省去了max_flow中的第一个for循环
  23. if(vis[i]==0 && i!=now && cap[now][i]-flow[now][i]>0)
  24. {
  25. q.push(i);
  26. pre[i]=now;
  27. vis[i]=min(vis[now], cap[now][i]-flow[now][i]);
  28. if(i==t) return true; //找到了
  29. }
  30. }
  31. }
  32. return false;
  33. }
  34. int max_flow(int s,int t)
  35. {
  36. int ans=0;
  37. while(bfs(s,t))
  38. {
  39. //这个for循环的作用就是找到一条到达重点的路中,最小的剩余流量值
  40. // int delta=0x7fffffff;
  41. // for(int i=t;i!=s;i=pre[i])
  42. // {
  43. // delta=min(delta,cap[pre[i]][i]-flow[pre[i]][i]);
  44. // }
  45. for(int i=t;i!=s;i=pre[i])
  46. {
  47. // flow[pre[i]][i]+=delta;
  48. // flow[i][pre[i]]-=delta;
  49. flow[pre[i]][i]+=vis[t];
  50. flow[i][pre[i]]-=vis[t];
  51. }
  52. ans+=vis[t]; //这是一个结论 记住就行
  53. }
  54. return ans;
  55. }
  56. int main()
  57. {
  58. cin>>m>>n;
  59. for(int i=1;i<=m;i++)
  60. {
  61. int x,y,rl;
  62. cin>>x>>y>>rl;
  63. //必须是+= 超级阴人.....没有看到一处到另一处不止一条排水沟
  64. cap[x][y]+=rl;
  65. cap[y][x]+=rl;
  66. flow[x][y]=0;
  67. flow[y][x]+=rl;
  68. }
  69. cout<<max_flow(1,n);
  70. return 0;
  71. }
  1. //下面的代码是自己对《算法竞赛入门经典》中关于最大流的写法
  2. //因为这个题中,两个点之间不仅只有一条路,所以开始使用邻接矩阵,然后再使用加边函数来进行操作
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<vector>
  7. #include<queue>
  8. using namespace std;
  9. const int inf=0x3f3f3f3f;
  10. const int maxn=300;
  11. struct Edge{
  12. int from, to, cap, flow;
  13. Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f){}
  14. };
  15. vector<Edge> edges;
  16. vector<int> G[maxn];//邻接表,G[i][j],表示结点i的第j条边在edges[j]中。
  17. int vis[maxn], pre[maxn], cap[205][205];//pre用来记录路径
  18. int n, m;
  19. void init()
  20. {
  21. for(int i=0; i<=n; i++) G[i].clear();
  22. edges.clear();
  23. }
  24. inline void addedge(int from, int to, int cap) //这里使用了inline函数,一定条件下可以减少运行时间
  25. {
  26. edges.push_back(Edge(from, to, cap, 0));
  27. edges.push_back(Edge(to, from, cap, cap));
  28. int m=edges.size();
  29. G[from].push_back(m-2);
  30. G[to].push_back(m-1);
  31. }
  32. bool bfs(int s, int t)
  33. {
  34. memset(vis, 0,sizeof(vis));
  35. queue<int> Q;
  36. Q.push(s);
  37. vis[s]=inf;
  38. while(!Q.empty())
  39. {
  40. int x=Q.front(); Q.pop();
  41. for(int i=0; i<G[x].size(); i++)
  42. {
  43. Edge &e=edges[G[x][i]];
  44. if(!vis[e.to] && e.cap > e.flow)
  45. {
  46. pre[e.to]=G[x][i];
  47. vis[e.to]=min(vis[x], e.cap-e.flow);
  48. Q.push(e.to);
  49. }
  50. }
  51. if(vis[t]) return true;
  52. }
  53. return false;
  54. }
  55. int maxflow(int s, int t)
  56. {
  57. int flow = 0;
  58. while(bfs(s, t))
  59. {
  60. for(int u=t; u!=s; u=edges[pre[u]].from)
  61. {
  62. edges[pre[u]].flow += vis[t];
  63. edges[pre[u]^1].flow -= vis[t];
  64. }
  65. flow += vis[t];
  66. }
  67. return flow;
  68. }
  69. int main()
  70. {
  71. int x, y, rl;
  72. scanf("%d%d", &m, &n);
  73. memset(cap, 0, sizeof(cap));
  74. for(int i=1; i<=m; i++)
  75. {
  76. scanf("%d%d%d", &x, &y, &rl);
  77. cap[x][y]+=rl;
  78. }
  79. for(int i=1; i<=n; i++)
  80. {
  81. for(int j=1; j<=n; j++)
  82. {
  83. if(cap[i][j]!=0)
  84. addedge(i, j, cap[i][j]);
  85. }
  86. }
  87. printf("%d\n", maxflow(1, n));
  88. return 0;
  89. }

草地排水 洛谷P2740 最大流 入门题目的更多相关文章

  1. bzoj 5120 无限之环 & 洛谷 P4003 —— 费用流(多路增广SPFA)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5120 https://www.luogu.org/problemnew/show/P4003 ...

  2. 洛谷P2740 [USACO4.2]草地排水Drainage Ditches

    题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...

  3. 洛谷P2740 草地排水

    最大流 一道完全符合最大流定义的板子题..重新学了一次网络流,希望有更深的理解把.. #include <bits/stdc++.h> #define INF 0x3f3f3f3f #de ...

  4. 【USACO4.2】草地排水Drainage Ditches(最大流)

    题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...

  5. 洛谷P2604 最大流+最小费用最大流

    题目链接:https://www.luogu.org/problem/P2604 题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在 ...

  6. 【学术篇】树上差分--洛谷3128最大流Max Flow

    懒得贴题目,直接放不稳定的传送门(雾):点击前往暴风城(雾) 据说这题是BZOJ3490,但本蒟蒻没有权限╮(╯_╰)╭ 这题似乎就是裸树上差分... 对于树上(x,y)之间的路径上的点区间c[i]加 ...

  7. 【洛谷T7152】(考试题目)细胞

    题面 题目描述 小 X 在上完生物课后对细胞的分裂产生了浓厚的兴趣.于是他决定做实验并 观察细胞分裂的规律. 他选取了一种特别的细胞,每天每个该细胞可以分裂出 x − 1 个新的细胞. 小 X 决定第 ...

  8. 【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)

    题目: 洛谷2469 分析: 把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小.从点\(i\)开始的路径需要额外加上\(A_i\)的权值. 回xian忆chang一xue下 ...

  9. DP【洛谷P2363】马农

    [洛谷P2363]马农 题目描述 在观看完战马检阅之后,来自大草原的两兄弟决心成为超级"马农",专门饲养战马. 兄弟两回到草原,将可以养马的区域,分为N*N的单位面积的正方形,并实 ...

随机推荐

  1. JavaWeb_(Hibernate框架)Hibernate中创建实体

    Hibernate中创建实体 创建实体五个基本规则 --提供无参的构造器 --成员变量的私有化,提供get.set方法,提供属性 --尽量使用包装类型 --主键(一定要有) --不要加final(hi ...

  2. 2.6.2 XML配置:使用testNG进行并发多浏览器测试

    测试类 1 @Parameters("browser") 定义browser参数. 在测试执行过程中,browser参数具体值由XML文件进行传递. 1 2 3 4 5 6 7 8 ...

  3. ubuntu 下vscode 修改主题 注释斜体

    找到vscode的程序目录 全局搜索extensions 找到目录 /home/your_usr_name/.vscode/extensions 这里修改 注释字体 直接删掉fontStyle for ...

  4. Java内存缓存-通过Map定制简单缓存

    缓存 在程序中,缓存是一个高速数据存储层,其中存储了数据子集,且通常是短暂性存储,这样日后再次请求此数据时,速度要比访问数据的主存储位置快.通过缓存,可以高效地重用之前检索或计算的数据. 为什么要用缓 ...

  5. Python 图形界面元素

    from tkinter import * import os def button_click1(): try: filePath = r'D:\CloudMusic' os.system(&quo ...

  6. Liunx 命令之链接操作

    Linux 系统中有软链接和硬链接两种特殊的"文件". 软链接可以看作是Windows中的快捷方式,可以让你快速链接到目标档案或目录. 硬链接则透过文件系统的inode来产生新档名 ...

  7. dokcer部署code-server web版vscode

    #dokcer部署code-server web版vscode codercom/code-server:latest不支持插件在线安装 codercom/code-server:v2目前为最新版1. ...

  8. C# Await

    每次提到异步我都选择绕开,感觉深不可测,最近打算看看异步,但又不愿意看书,网上找了几个视频看,发现传智播客的老师讲异步都不是很深入,关键的问题一笔带过,倒是把我弄糊涂了,印象最深刻的是那个老师说的一句 ...

  9. CentOS 6 系统基础配置

    系统版本:CentOS 6.8 Minimal 采用最小化系统安装,许多组件默认是不安装的,通过手工安装一些常用工具包,让系统用起来更顺手. 1.设置机器名: # echo "NETWORK ...

  10. CDH spark 命令行测试

    一. 参考 https://www.cnblogs.com/bovenson/p/5801536.html [root@node- test]# chown hdfs:hdfs /root/test/ ...