Landscaping Gym - 101128F (网络流)
Problem F: Landscaping
\]
题意
题意是给出一个\(n*m\)的格子,其中一些是低海拔的,一些是高海拔的,然后有\(n+m\)辆推土车从左到右,从上到下推过去,推土车在不同高度的块之前走需要花费\(A\)元,也可以花费\(B\)元改变一个块的海拔
思路
这个网络流真的好骚啊...
先说建图怎么建图,建图分成三步
- 从源点到所有低海拔的块建一条\(B\)流量的边
- 从所有高海拔的块到汇点建一条\(B\)流量的边
- 对于所有块,想四个方向建一条\(A\)流量的边
考虑其中的一条流量。
源点\(\frac{B}{——>}\)低海拔\(\frac{A}{——>}\)高海拔\(\frac{B}{——>}\)汇点
如果\(A>B\),那么能跑出的最大流是\(B\),也就是花费\(B\)元把低海拔变为高海拔或者把高海拔变为低海拔,如果\(B>A\),那么跑出的最大流是\(A\),也就是花费\(A\)元从低海拔走到高海拔。
我们发现,这个最大流,一定是这三条边中的最小值。思考他们的意义,如果选择第一条边或第三条边,也就是把低海拔变为高海拔或者高海拔变为低海拔,那么这时候网络流中\(A\)被忽略了,也符合实际意义,已经改变了块的海拔,不用花费\(A\)元在不同块之间走。如果选择第二条边,也就是从低海拔走到高海拔,这时候\(B\)被忽略,也符合实际意义不修改这个块的海拔,而是直接走。
那么为什么一个块要对四个方向建边而不是向四个方向上存在海拔差的块建边呢?因为网络流跑的过程中,旁边的块可能发生了海拔变化,我们无法知道哪些发生了变化,所以都要建一个\(A\)的边。
所以在网络流跑的时候,由于限制条件的存在,他这样建边跑出来的最大流就是答案。
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout)
typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std;
int n, m, A, B;
int cas, tol, T;
struct Node{
int v, w;
int next;
} node[maxn];
int dis[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
char s[100][100];
int head[maxn];
int dep[maxn];
int getid(int x, int y) {
return (x-1)*m+y;
}
void init() {
tol = 0;
mes(head, -1);
}
void addnode(int u, int v, int w) {
node[tol].v = v;
node[tol].w = w;
node[tol].next = head[u];
head[u] = tol++;
}
bool bfs(int src, int des) {
mes(dep, -1);
dep[src] = 0;
queue<int> q;
while(!q.empty()) q.pop();
q.push(src);
while(!q.empty()) {
int u = q.front();
q.pop();
if(u == des) return true;
for(int i=head[u]; ~i; i=node[i].next) {
int v = node[i].v;
if(dep[v] == -1 && node[i].w) {
dep[v] = dep[u]+1;
q.push(v);
}
}
}
return false;
}
int dfs(int src, int des, int flow) {
if(src == des) return flow;
int ans = 0;
for(int i=head[src]; ~i; i=node[i].next) {
int v = node[i].v;
if(dep[v] == dep[src]+1 && node[i].w) {
int tmp = dfs(v, des, min(node[i].w, flow-ans));
node[i].w -= tmp;
node[i^1].w += tmp;
ans += tmp;
if(ans == flow) return ans;
}
}
if(!ans) dep[src] = -2;
return ans;
}
int dinic(int src, int des) {
int ans = 0, tmp;
while(bfs(src, des)) {
while((tmp = dfs(src, des, inf)) > 0) {
ans += tmp;
}
}
return ans;
}
int main() {
init();
scanf("%d%d%d%d", &n, &m, &A, &B);
int src = 0, des = n*m+1;
for(int i=1; i<=n; i++) {
scanf("%s", s[i]+1);
for(int j=1; j<=m; j++) {
if(s[i][j] == '.') {
addnode(src, getid(i, j), B);
addnode(getid(i, j), src, 0);
} else {
addnode(getid(i, j), des, B);
addnode(des, getid(i, j), 0);
}
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
for(int k=0; k<4; k++) {
int x = i+dis[k][0];
int y = j+dis[k][1];
if(x<1 || y<1 || x>n || y>m) continue;
addnode(getid(i, j), getid(x, y), A);
addnode(getid(x, y), getid(i, j), 0);
}
}
}
int ans = dinic(src, des);
printf("%d\n", ans);
return 0;
}
Landscaping Gym - 101128F (网络流)的更多相关文章
- Gym - 101128F Landscaping(网络流)
题意 给你一个\(N×M\)的草地,有高地有低地. 收割机从低地走到高地或者从高地走到低地都要花费用\(A\),你可以花费用\(B\)把一块高地变成低地,或者把一块低地变成高地.收割机每行每列都是必须 ...
- Gym 101128F Landscaping(网络流)题解
题意:n*m的地,从有高地和低地,从高地走到低地或者从低地走到高地花费a,把高地和低地互相改造一次花费b.现在要走遍每一行每一列,问最小花费 思路:超级源点连接所有低地,容量b:所有地向四周建边,容量 ...
- Gym 101128F Sheldon Numbers(网络流)
[题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ...
- 【最小割】【Dinic】Gym - 101128F - Landscaping
http://blog.csdn.net/lxy767087094/article/details/68942422 #include<cstdio> #include<cstrin ...
- Gym - 100203I I WIN 网络流
Gym - 100203I I WIN 题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN. 思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下 ...
- C - Portals Gym - 102006C (网络流最小割)
题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ...
- 【bzoj4439】[Swerc2015]Landscaping 网络流最小割
题目描述 FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示) FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示 对于一个4*4的田 ...
- codeforce Gym 100203I I WIN (网络流)
把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能 ...
- codeforces gym 100357 J (网络流)
题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...
随机推荐
- The Preliminary Contest for ICPC Asia Nanjing 2019/2019南京网络赛——题解
(施工中……已更新DF) 比赛传送门:https://www.jisuanke.com/contest/3004 D. Robots(期望dp) 题意 给一个DAG,保证入度为$0$的点只有$1$,出 ...
- CSP2019-S宝典
目录 CSP2019-S宝典 模板 博客 快读 vim配置 对拍 CSP2019-S注意事项 考前 考时 考后 游记 Day -2(UPDATE:2019-11-14) Day -1(UPDATE:2 ...
- (原创)如何搭建PLC+上位机监控系统达到成本的最小化?
以西门子PLC举例; 西门子PLC有几个型号:S7-200SMART,S7-1200,S7-300,S7-400,S7-1500,价格从低到高. 1个项目中要求的IO数量:600点的DI+DO,若干个 ...
- C#表达式参数解析算法,N级属性调用,函数值,变量值,常量值
public static object GetValue(Expression expression) { var names = new Stack<string>(); var ex ...
- C# Linq 使用总结
隐式类型匿名类型自动属性初始化器委托泛型泛型委托匿名方法Lambda表达式扩展方法迭代器LINQ System.Linq var arr = new[] { "c", " ...
- Spring IOC 概述
Spring IOC 概述 IOC(Inversion of Control) 控制反转,也叫 DI(D_ependency injection_) 依赖注入.是一种设计思想.不过我并不同意所谓反转的 ...
- Ubuntu系统下搭建docke
linux内核版本依赖 kernel version >= 3.8 可以使用如下命令查看 uname -a | awk '{split($3, arr, "-"); prin ...
- C# LINQ干掉for循环
public void OldSum() { ; ; i < ; i++) { sum0 += i; } Assert.AreEqual(, sum0); } public void NewSu ...
- PHP-FPM的相关知识的深度解释
一.需要搞清楚几个名词概念 1. CGI(Common Gateway Interface,CGI)通用网关接口, 是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展 ...
- JavaScript---Bom树的操作,内置方法和内置对象(window对象,location对象,navigator对象,history对象,screen对象)
JavaScript---Bom树的操作,内置方法和内置对象(window对象,location对象,navigator对象,history对象,screen对象) 一丶什么是BOM B ...