草地排水 洛谷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)是这条排水沟的最大容量。

输出格式

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

//下面是样例输入
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
//样例输出
50

解题思路

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

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

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

代码实现

//我的EK写法。。。建议邻接矩阵
//题目:洛谷p2740 草地排水
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int m,n,cap[205][205],pre[205],flow[205][205];
int vis[205];
bool bfs(int s,int t)
{
// memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
queue<int> q;
q.push(s);
vis[s]=inf;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
//这里vis不仅代表标记,还记录了到这个结点可以减去的最小流量值
//这样就省去了max_flow中的第一个for循环
if(vis[i]==0 && i!=now && cap[now][i]-flow[now][i]>0)
{
q.push(i);
pre[i]=now;
vis[i]=min(vis[now], cap[now][i]-flow[now][i]);
if(i==t) return true; //找到了
}
}
}
return false;
}
int max_flow(int s,int t)
{
int ans=0; while(bfs(s,t))
{
//这个for循环的作用就是找到一条到达重点的路中,最小的剩余流量值
// int delta=0x7fffffff;
// for(int i=t;i!=s;i=pre[i])
// {
// delta=min(delta,cap[pre[i]][i]-flow[pre[i]][i]);
// }
for(int i=t;i!=s;i=pre[i])
{
// flow[pre[i]][i]+=delta;
// flow[i][pre[i]]-=delta;
flow[pre[i]][i]+=vis[t];
flow[i][pre[i]]-=vis[t];
}
ans+=vis[t]; //这是一个结论 记住就行
}
return ans;
}
int main()
{
cin>>m>>n;
for(int i=1;i<=m;i++)
{
int x,y,rl;
cin>>x>>y>>rl;
//必须是+= 超级阴人.....没有看到一处到另一处不止一条排水沟
cap[x][y]+=rl;
cap[y][x]+=rl;
flow[x][y]=0;
flow[y][x]+=rl;
}
cout<<max_flow(1,n);
return 0;
}
//下面的代码是自己对《算法竞赛入门经典》中关于最大流的写法
//因为这个题中,两个点之间不仅只有一条路,所以开始使用邻接矩阵,然后再使用加边函数来进行操作
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=300;
struct Edge{
int from, to, cap, flow;
Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f){}
};
vector<Edge> edges;
vector<int> G[maxn];//邻接表,G[i][j],表示结点i的第j条边在edges[j]中。
int vis[maxn], pre[maxn], cap[205][205];//pre用来记录路径
int n, m;
void init()
{
for(int i=0; i<=n; i++) G[i].clear();
edges.clear();
}
inline void addedge(int from, int to, int cap) //这里使用了inline函数,一定条件下可以减少运行时间
{
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, cap, cap));
int m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool bfs(int s, int t)
{
memset(vis, 0,sizeof(vis));
queue<int> Q;
Q.push(s);
vis[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(!vis[e.to] && e.cap > e.flow)
{
pre[e.to]=G[x][i];
vis[e.to]=min(vis[x], e.cap-e.flow);
Q.push(e.to);
}
}
if(vis[t]) return true;
}
return false;
}
int maxflow(int s, int t)
{
int flow = 0;
while(bfs(s, t))
{
for(int u=t; u!=s; u=edges[pre[u]].from)
{
edges[pre[u]].flow += vis[t];
edges[pre[u]^1].flow -= vis[t];
}
flow += vis[t];
}
return flow;
}
int main()
{
int x, y, rl;
scanf("%d%d", &m, &n);
memset(cap, 0, sizeof(cap));
for(int i=1; i<=m; i++)
{
scanf("%d%d%d", &x, &y, &rl);
cap[x][y]+=rl;
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(cap[i][j]!=0)
addedge(i, j, cap[i][j]);
}
}
printf("%d\n", maxflow(1, n));
return 0;
}

草地排水 洛谷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. noi.ac #553 序列

    [题目描述] 老虎和蒜头是好朋友. 众所周知,蒜头经常给老虎出一些题目,而老虎也常常被难倒,作为捧杯之王的老虎难免心有怨怼.今天,老虎发现了蒜头的一个序列 a​ .虽然老虎不知道这个序列是用来做什么的 ...

  2. Node.js安装及环境配置

     1.Node.js简介 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js ...

  3. HDU 5791 Two ——(LCS变形)

    感觉就是最长公共子序列的一个变形(虽然我也没做过LCS啦= =). 转移方程见代码吧.这里有一个要说的地方,如果a[i] == a[j]的时候,为什么不需要像不等于的时候那样减去一个dp[i-1][j ...

  4. 三、Reids(高性能)key-value服务器知识整合

    一.Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. 知识链接:https://www.runoob.com/redis/redis-backup.html ht ...

  5. Rust格式化输出

    打印操作由 https://doc.rust-lang.org/std/fmt/ 里面所定义的一系列宏来处理,包括: format!:将格式化文本写到字符串(String).(译注:字符串是返 回值不 ...

  6. nginx中location匹配规则介绍

    一,匹配规则 1,= 表示精确匹配 例子:http://localhost/  将匹配到 location = / {...} http://localhost/aaa  可以匹配到 location ...

  7. koa 基础(十四)cookie 的基本使用

    1.app.js /** * cookie的简介: * 1.cookie保存在浏览器客户端 * 2.可以让我们用同一个浏览器访问同一个域名的时候共享数据 * * cookie的作用: * 1.保存用户 ...

  8. 网络配置及一些shell命令概览

    一.临时配置网络(ip,网关,dns)+永久配置 1.临时配置网络IP地址命令为“ifconfig 网卡名 ip地址/24”,例如: ifconfig eth0 192.168.16.253/24 2 ...

  9. 关于ansbile

    YAML语法规则 规则一:缩进(一个缩进两空格,注意一定不用tab) 规则二:冒号(每个冒号后一定要有空格) 规则三:短横线 - (短横线后面要空格) 编写案例 ansible-playbook -- ...

  10. image-webpack-loader在mac或ubuntu报错

    解决办法安装libpng库,在github issue https://github.com/tcoopman/image-webpack-loader/issues/49可查看 mac: brew ...