草地排水 洛谷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. zabbix服务端接收的数据类型,便于编写脚本向服务端提交数据

    1.数据类型1:zabbix_agent执行脚本提交字典 UserParameter=tcp_port_listen,/usr/local/zabbix/share/script/get_game_p ...

  2. JavaWeb-SpringBoot(抖音)_一、抖音项目制作

    JavaWeb-SpringBoot(抖音)_一.抖音项目制作 传送门 JavaWeb-SpringBoot(抖音)_二.服务器间通讯 传送门 JavaWeb-SpringBoot(抖音)_三.抖音项 ...

  3. Ansible常用模块之系统类模块

    cron模块 管理远程主机上的计划任务 [root@tiandong ansible]# ansible all -m cron -a "name='cron test' minute=5 ...

  4. python3 输入与输出

    pyhon3 io 输入和输出myread=open('E:/路径.txt')#open()会将返回一个file对象mywrite=open('E:/3/路径.txt','w')#后面w是如果文件存在 ...

  5. 图片上传(前端显示预览,后端php接收)

    html: <form action="{:Url('do_ls_law_upload')}" method="POST" accept-charset= ...

  6. 调用远程linux服务器shell脚本

    package com.haiyisoft.hyoaPc.ui; import java.io.BufferedReader;import java.io.IOException;import jav ...

  7. struts数据回显

    数据回显,必须要用struts标签! Action中: // 进入修改页面 public String viewUpdate() { // 模拟一个对象(先获取一个id,再根据id调用service查 ...

  8. IIS 报错试图加载格式不正确的程序集解决办法

    原因: 64位系统和32系统不匹配导致. 解决办法: 方法一.注册32位IIS(必须卸载64位IIS) 使用命令 X:WindowsMicrosoft.NETFramework64v4.0.30319 ...

  9. Java生成三位随机数

    转: [转]Java生成三位随机数 public class Test2 { public static void main(String [] srgs) { int i=(int)(Math.ra ...

  10. 简单配置 docker swarm

    #准备三台CentOS7 #IP划分 192.168.1.201       virtualBox1 192168.1.202        virtualBox2 192168.1.204      ...