【网络流】[USACO4.2]草地排水Drainage Ditches
用EdmondsKarp可过
题目背景
在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。
题目描述
农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。
根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。
输入输出格式
输入格式:
第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)是这条排水沟的最大容量。
输出格式:
输出一个整数,即排水的最大流量。
题目分析
嗯这就是一道EdmondsKarp的模板题。(时间复杂度:O(NM²))
对于EdmondsKarp这个算法,重点在于它的增广操作。因为每一次增广是对于路径上的单独一条流而言的,所以需要搜索每一条s→t的流,并且回溯增广这条流上的流量,因此实现方式应该选择BFS而非DFS(DFS太容易被卡挂了)。
这个算法还有一个巧妙的地方,就是它不仅更新s→t的流量使其加上delta,同时更新t→s的流量使其减去delta(残量网络建图)。这样可以解决一些本应该需要指数级复杂度才能解决的麻烦情况。
一边冷静分析一边抄的刘汝佳的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+;
const int INF = 2e9;
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],p[maxn]; void init(int n) //初始化
{
for (int i=; i<=n; i++)G[i].clear();
edges.clear();
} void add_edge(int from, int to, int cap) //邻接表加边
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
int mx = edges.size();
G[from].push_back(mx-);
G[to].push_back(mx-); //一对相反弧存在一起。所以编号分别为x,x^1(异或)
} long long Maxflow(int s, int t) //s→t的最大流
{
long long flow = ;
for (;;)
{
memset(a, , sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while (Q.size()) //BFS搜索
{
int x = Q.front();Q.pop();
for (int i=; 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; //如果终点可增广,则退出BFS
}
if (!a[t])break; //如果搜索完之后终点仍然不可增广,则退出最大流过程
for (int u=t; u!=s; u = edges[p[u]].from) //回溯增广
{
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
flow += a[t];
}
return flow;
}
}f;
int read() //对快读不熟悉的后果!最早是没写return,后来发现ch应该要getchar()读入。于是读入这里使得程序从 9272ms→ 632ms!
{ //还以为EK写错了……
char ch=getchar();int num = ;
while (ch<''||ch>'')ch = getchar();
while (ch>=''&&ch<=''){num=num*+ch-'';ch = getchar();}
return num;
}
int main()
{
scanf("%d%d",&f.m,&f.n);
f.init(f.n);
for (int i=; i<=f.m; i++)
{
int x = read(), y = read(), z = read();
f.add_edge(x, y, z);
}
printf("%lld\n",f.Maxflow(, f.n));
}
另附:
1.Cptraser:www.cnblogs.com/Cptraser/p/7921455.html
2.网络:blog.sina.com.cn/s/blog_6cf509db0100uy5n.html
听说NOIp提高组不考网络流的样子(?)下午继续去做usacoTraing
【网络流】[USACO4.2]草地排水Drainage Ditches的更多相关文章
- luogu P2740 [USACO4.2]草地排水Drainage Ditches |网络流
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- 最大流 [USACO4.2]草地排水Drainage Ditches
Background 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免 ...
- [USACO4.2]草地排水Drainage Ditches
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草 要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹 ...
- 洛谷P2740 [USACO4.2]草地排水Drainage Ditches
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- [USACO4.2] 草地排水 Drainage Ditches (最大流)
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- P2740 [USACO4.2]草地排水Drainage Ditches
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- luogu2740 [USACO4.2]草地排水Drainage Ditches 最大流EK
练一下最大流 #include <iostream> #include <cstring> #include <cstdio> #include <queue ...
- 【USACO4.2】草地排水Drainage Ditches(最大流)
题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没 ...
- 网络流--最大流--POJ 1273 Drainage Ditches
链接 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clov ...
随机推荐
- JS实现购物车动态功能
整理了一下当时学js写的一些案例,觉得购物车功能在一般网站比较常见且基础,现在把它整理出来,需要的小伙伴可以参考一下. 该案例购物车主要功能如下: 1. 商品单选.全选.反选功能 2. 商品添加.删除 ...
- nacos启动
nacos下载 https://github.com/alibaba/nacos 1.执行数据库脚本 2.修改配置文件application.propertiesspring.datasource.p ...
- shell 截取字符串(转)
linux中对字符串的处理: 1.字符串分割例如 AAAAA-BBBBBB 按-分割去前后两部分 cut : [rich@localhost ~]$ str=AAAAA-BBBBBB[rich@l ...
- 51Nod 1043 幸运号码
#include <stdio.h> #include <algorithm> using namespace std; typedef long long ll; ; ][] ...
- java快速排序代码
public class test1 { public static int partition(int[] array,int lo,int hi){ int key=array[lo]; whil ...
- Python入门小练习
Python入门小练习 001 备份文件 Python入门小练习 002 批量下载网页链接中的图片 Python入门小练习 003 利用cookielib模拟登录获取账户信息
- python 基础(十五) socket编程
SOCKET TCP协议: 有请求 有响应 称之为 tcp协议 是面向连接的协议 就是在收发数据之前 必须先要建立一个可靠的链接 三次握手 如:网站 UDP协议: 是一个非链接的协议 传输之前不需要键 ...
- BZOJ1218(线段树+扫描线)
1.扫描线扫描x轴,线段树维护y轴. 2.坐标+1,线段树是从1开始维护.然后让边长--,这样就能包含边上的点了. 3.为了保证点在正方形内:在x轴上利用差分的思想,在x出Add(val),在x+r( ...
- 安卓Listview 不规则项即不同item的运行
在安卓中,listview 的item 是一个不断被轮询调换位置的过程,这样 即 图片参考地址 http://www.cnblogs.com/mybkn/archive/2012/05/23/2 ...
- java中的线程安全是什么?什么叫线程安全?什么叫不安全?
java中的线程安全是什么: 就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问 什么叫 ...