Problem F: Landscaping

\[Time Limit: 1 s \quad Memory Limit: 256 MiB
\]

题意

题意是给出一个\(n*m\)的格子,其中一些是低海拔的,一些是高海拔的,然后有\(n+m\)辆推土车从左到右,从上到下推过去,推土车在不同高度的块之前走需要花费\(A\)元,也可以花费\(B\)元改变一个块的海拔

思路

这个网络流真的好骚啊...

先说建图怎么建图,建图分成三步

  1. 从源点到所有低海拔的块建一条\(B\)流量的边
  2. 从所有高海拔的块到汇点建一条\(B\)流量的边
  3. 对于所有块,想四个方向建一条\(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 (网络流)的更多相关文章

  1. Gym - 101128F Landscaping(网络流)

    题意 给你一个\(N×M\)的草地,有高地有低地. 收割机从低地走到高地或者从高地走到低地都要花费用\(A\),你可以花费用\(B\)把一块高地变成低地,或者把一块低地变成高地.收割机每行每列都是必须 ...

  2. Gym 101128F Landscaping(网络流)题解

    题意:n*m的地,从有高地和低地,从高地走到低地或者从低地走到高地花费a,把高地和低地互相改造一次花费b.现在要走遍每一行每一列,问最小花费 思路:超级源点连接所有低地,容量b:所有地向四周建边,容量 ...

  3. Gym 101128F Sheldon Numbers(网络流)

    [题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ...

  4. 【最小割】【Dinic】Gym - 101128F - Landscaping

    http://blog.csdn.net/lxy767087094/article/details/68942422 #include<cstdio> #include<cstrin ...

  5. Gym - 100203I I WIN 网络流

    Gym - 100203I  I WIN 题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN. 思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下 ...

  6. C - Portals Gym - 102006C (网络流最小割)

    题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ...

  7. 【bzoj4439】[Swerc2015]Landscaping 网络流最小割

    题目描述 FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示) FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示 对于一个4*4的田 ...

  8. codeforce Gym 100203I I WIN (网络流)

    把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能 ...

  9. codeforces gym 100357 J (网络流)

    题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...

随机推荐

  1. Sitecore安全:访问权限

    由于Sitecore使用Core数据库中的项来定义其用户界面,因此您可以对该数据库中的项应用访问权限,以控制对CMS功能的访问.最常见的是,将用户置于预定义的Sitecore客户端角色中 Siteco ...

  2. scala 函数式编程之集合操作

    Scala的集合体系结构 // Scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trai.这个结构与Java的集合体系非常相似. ...

  3. FusionInsight大数据开发---Hive应用开发

    Hive应用开发 了解Hive的基本架构原理 掌握JDBC客户端开发流程 了解ODBC客户端的开发流程 了解python客户端的开发流程 了解Hcatalog/webHcat开发接口 掌握Hive开发 ...

  4. phoenix kerberos 连接配置

    1. 官网资料 Use JDBC to get a connection to an HBase cluster like this: Connection conn = DriverManager. ...

  5. Entity Framework 学习系列(3) - MySql Code First 开发方式+数据迁移

    目录 # 写在前面 一.开发环境 二.创建项目 三.安装程序包 四.创建模型 五.连接字符串 六.编辑程序 七.数据迁移 写在最后 # 写在前面 这几天,一直都在学习Entity Framework ...

  6. SecureCRT上传本地文件到linux

    1.使用crt登录到需要操作的linux系统 2.按Alt+P打开sftp传输界面 3.输入pur指令加文件路径,例如:put E://srs-3.0.zip按enter就可以 4.再返回crt界面, ...

  7. drf之组件(认证、权限、排序、过滤、分页等)和xadmin、coreapi

    认证Authentication 可以在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_fr ...

  8. 创建mybatis的逆向工程

    1.mybatis的逆向工程(我使用的是maven仓库创建) 工作原理:反向工程(通过数据库中的表和字段信息去生成对应的增删改查方法) 其实就是一个自动生成工具 生成实体类(pojo)和映射文件(ma ...

  9. Go语言入门——函数

    写了快一个月的Go,已经没有什么陌生感了. 一行代码写完,不会在行尾本能的敲上“:”,直接Enter键换行: 定义变量把变量名放在前面,类型放在后面: 使用struct去定义自己想要的数据模型就好比定 ...

  10. 数据结构与算法5—KMP算法

    串的模式匹配算法 子串(模式串)的定位操作通常称为串的模式匹配. 这是串的一种重要操作,很多 软件,若有“编辑”菜单项的话, 则其中必有“查找”子菜单项. 串的顺序存储实现 #include<s ...