Luogu P3227 [HNOI2013]切糕 最小割
首先推荐一个写的很好的题解,个人水平有限只能写流水账,还请见谅。
经典的最小割模型,很多人都说这个题是水题,但我还是被卡了=_=
技巧:加边表示限制
在没有距离\(<=d\)的限制时候,我们对每个竖轴连一条完整的边跑最小割即可(效果和取\(min\)是一样的)。但是现在需要加入这个限制,我们就要考虑加边。
原条件:\(|x - y| <= d\)
转化为:\(x - y <= d\) 且 \(y - x <= d\)
我们考虑对每一个不等式单独处理,实际上可以转化为:
对于每一个\(x\),和它四联通的所有\(y\)都满足\(y >= x - d\)。
这个不等式的限制如何满足?我们考虑添加\(x_h -> y_{h - d}\)。比如如果\(d\)是\(2\)的话:
图中如果可以在在\(x\)上和\(y\)上割掉两条边,那么一定有\(y >= x - 2\),因为割掉\(y < x - 2\)的边并不能完全割断原图,所以没有意义。
那么我们就对每个\(x\)向其四联通的位置这样连边就可以了。
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
const int M = 400010;
const int INF = 0x3f3f3f3f;
int n, m, h, d, cnt = -1, head[N];
int mv[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct edge {int nxt, to, f;}e[M];
void add_len (int u, int v, int f) {
e[++cnt] = (edge) {head[u], v, f}; head[u] = cnt;
e[++cnt] = (edge) {head[v], u, 0}; head[v] = cnt;
}
bool in_map (int x, int y, int z) {
return 1 <= x && x <= n && 1 <= y && y <= m && 1 <= z && z <= h;
}
int inn (int x, int y, int z) {return n * m * h * 0 + (x - 1) * m * h + (y - 1) * h + z;}
int out (int x, int y, int z) {return n * m * h * 1 + (x - 1) * m * h + (y - 1) * h + z;}
queue <int> q;
int cur[N], deep[N];
bool bfs (int s, int t) {
memcpy (cur, head, sizeof (head));
memset (deep, 0x3f, sizeof (deep));
q.push (s); deep[s] = 0;
while (!q.empty ()) {
int u = q.front (); q.pop ();
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].to;
if (deep[v] == INF && e[i].f) {
deep[v] = deep[u] + 1;
q.push (v);
}
}
}
return deep[t] != INF;
}
int dfs (int u, int t, int lim) {
if (u == t || !lim) {
return lim;
}
int tmp = 0, flow = 0;
for (int &i = cur[u]; ~i; i = e[i].nxt) {
int v = e[i].to;
if (deep[v] == deep[u] + 1) {
tmp = dfs (v, t, min (lim, e[i].f));
lim -= tmp;
flow += tmp;
e[i ^ 0].f -= tmp;
e[i ^ 1].f += tmp;
if (!lim) break;
}
}
return flow;
}
int Dinic (int s, int t) {
int min_cut = 0;
while (bfs (s, t)) {
min_cut += dfs (s, t, INF);
}
return min_cut;
}
int main () {
memset (head, -1, sizeof (head));
cin >> n >> m >> h >> d;
int s = n * m * h * 2 + 1;
int t = n * m * h * 2 + 2;
int _val = 0;
for (int z = 1; z <= h; ++z) {
for (int x = 1; x <= n; ++x) {
for (int y = 1; y <= m; ++y) {
cin >> _val;
add_len (inn (x, y, z), out (x, y, z), _val);
if (in_map (x, y, z + 1)) {
add_len (out (x, y, z), inn (x, y, z + 1), INF);
}
for (int i = 0; i < 4; ++i) {
int tx = x + mv[i][0];
int ty = y + mv[i][1];
if (in_map (tx, ty, z - d)) {
add_len (out (x, y, z), inn (tx, ty, z - d), INF);
}
}
}
}
}
for (int x = 1; x <= n; ++x) {
for (int y = 1; y <= m; ++y) {
add_len (s, inn (x, y, 1), INF);
add_len (out (x, y, h), t, INF);
}
}
cout << Dinic (s, t) << endl;
}
Luogu P3227 [HNOI2013]切糕 最小割的更多相关文章
- bzoj3144 [HNOI2013]切糕(最小割)
bzoj3144 [HNOI2013]切糕(最小割) bzoj Luogu 题面描述见上 题解时间 一开始我真就把这玩意所说的切面当成了平面来做的 事实上只是说相邻的切点高度差都不超过 $ d $ 对 ...
- bzoj 3144: [Hnoi2013]切糕 最小割
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 681 Solved: 375[Submit][Status] ...
- 【BZOJ3144】[Hnoi2013]切糕 最小割
[BZOJ3144][Hnoi2013]切糕 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q ...
- BZOJ3144[Hnoi2013]切糕——最小割
题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...
- Luogu P3227 [HNOI2013]切糕
%%ZZKdalao上课讲的题目,才知道网络流的这种玄学建模 我们先想一想,如果没有D的限制,那么想当于再每一根纵轴上选一个权值最小的点再加起来 我们对应在网络流上就是每一根纵轴上的点向它下方的点用权 ...
- bzoj 3144 [Hnoi2013]切糕——最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3144 一根纵轴上切一个点,可以把一根纵轴上的点连成一串来体现.自己的写法是每个点连向前一个点 ...
- 洛谷 P3227 [HNOI2013]切糕(最小割)
题解 Dinic求最小割 题目其实就是求最小的代价使得每个纵轴被分成两部分 最小割!!! 我们把每个点抽象成一条边,一个纵轴就是一条\(S-T\)的路径 但是题目要求\(|f(x,y)-f(x',y' ...
- BZOJ3144/LG3227 「HNOI2013」切糕 最小割离散变量模型
问题描述 BZOJ3144 LG3227 还想粘下样例 输入: 2 2 2 1 6 1 6 1 2 6 2 6 输出: 6 题解 关于离散变量模型,我不想再抄一遍,所以: 对于样例,可以建立出这样的图 ...
- 【BZOJ-3144】切糕 最小割-最大流
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1261 Solved: 700[Submit][Status] ...
随机推荐
- 从0开始的Python学习003序列
sequence 序列 序列是一组有顺序数据的集合.不知道怎么说明更贴切,因为python的创建变量是不用定义类型,所以在序列中(因为有序我先把它看作是一个有序数组)的元素也不会被类型限制. 序列可以 ...
- C#中的值类型和引用类型,深拷贝,浅拷贝
from https://www.jianshu.com/p/2d27b06e253f 一.C#中的值类型和引用类型 概念 值类型直接存储其值. 引用类型存储对值的引用. 说起来有些拗口,其本质是Va ...
- SQL Server 查看CPU情况
--CPU相关视图 SELECT * FROM sys.dm_os_sys_info SELECT * FROM sys.dm_exec_sessions SELECT * FROM sys.sysp ...
- LeetCode算法题-Kth Largest Element in a Stream(Java实现)
这是悦乐书的第296次更新,第315篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第164题(顺位题号是703).设计一个类来查找流中第k个最大元素.请注意,它是排序顺序 ...
- Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Clien
https://blog.csdn.net/asahinokawa/article/details/84746422
- 贷款资讯类APP、贷款资讯网站廉价卖,需要的进来看看
[app介绍]卡贷资讯app为您提供信用卡申请攻略及借款资讯以及贷款口子,让你借钱借款路上不再愁.[功能特点]1.资讯:聚合各种贷款资讯知识,掌握核心信用卡申请攻略,借款借钱不亏,亦不被骗:2.工具: ...
- centos7 python环境安装
https://blog.csdn.net/LeonTom/article/details/81289326
- P1273 有线电视网
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...
- 使用Kernel NetEm和tc模拟复杂网络环境
关键词:netem(Network Emulator).tc(Traffic Control). 大部分局域网环境良好,但是产品实际网络环境可能千差万别,为了对产品进行各种情况测试就需要模拟网络环境. ...
- 基于Metronic的Bootstrap开发框架--工作流模块功能介绍(2)
本篇继续<基于Metronic的Bootstrap开发框架--工作流模块功能介绍>,继续介绍基于Metronic的Bootstrap开发框架的工作模块功能,介绍工作流模块中相关业务表单的界 ...