题目大意

切糕是 (p times q times r) 的长方体,每个点有一个违和感 (v_{x, y, z})。先要水平切开切糕(即对于每个纵轴,切面与其有且只有一个交点),要求水平上相邻两点的切面高度差小于等于 (D),求切面违和感和的最小值。

(1 leqslant p, ; q, ; r leqslant 40)

(0 leqslant v leqslant 1,000)

题目链接

BZOJ 3144

CodeVS 2997

题解

最小割。

用边连接相邻两个高度的的点,边 ((x, y, z - 1) rightarrow (x, y, z)) 容量为 (v_{x, y, z}),由源点发散出边连接第一层的每个点,最后一层的点收缩在汇点,这是没有(D)的限制是的答案。连接所有形如 ((x, y, z) rightarrow (x, y, z - D)) 的边,这样,当水平相邻的两个点切面差大于 (D) 时,最小割的图会由这样的边连在一起而没有被隔开。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <climits>
#include <queue>
#include <algorithm>
const int MAXN = 40;
struct ;
struct Node {
Edge *e, *curr;
int level;
} N[MAXN * MAXN * MAXN + 2];
struct {
Node *u, *v;
Edge *next, *rev;
int cap, flow;
Edge(Node *u, Node *v, int cap) : u(u), v(v), cap(cap), flow(0), next(u->e) {}
};
void addEdge(int u, int v, int cap) {
N[u].e = new Edge(&N[u], &N[v], cap);
N[v].e = new Edge(&N[v], &N[u], 0);
N[u].e->rev = N[v].e;
N[v].e->rev = N[u].e;
}
namespace Dinic {
bool makeLevelGraph(Node *s, Node *t, int n) {
for (int i = 0; i < n; i++) N[i].level = 0;
std::queue<Node *> q;
q.push(s);
s->level = 1;
while (!q.empty()) {
Node *u = q.front();
q.pop();
for (Edge *e = u->e; e; e 大专栏  [BZOJ 3144][HNOI 2013] 切糕= e->next) {
if (e->cap > e->flow && e->v->level == 0) {
e->v->level = u->level + 1;
if (e->v == t) return true;
q.push(e->v);
}
}
}
return false;
}
int findPath(Node *s, Node *t, int limit = INT_MAX) {
if (s == t) return limit;
for (Edge *&e = s->curr; e; e = e->next) {
if (e->cap > e->flow && e->v->level == s->level + 1) {
int flow = findPath(e->v, t, std::min(limit, e->cap - e->flow));
if (flow > 0) {
e->flow += flow;
e->rev->flow -= flow;
return flow;
}
}
}
return 0;
}
int solve(int s, int t, int n) {
int res = 0;
while (makeLevelGraph(&N[s], &N[t], n)) {
for (int i = 0; i < n; i++) N[i].curr = N[i].e;
int flow;
while ((flow = findPath(&N[s], &N[t])) > 0) res += flow;
}
return res;
}
}
int p, q, r;
int getID(int x, int y, int z) {
if (z == 0) return 0;
return (z - 1) * p * q + (x - 1) * q + y;
}
bool valid(int x, int y) {
return (x > 0) && (y > 0) && (x <= p) && (y <= q);
}
int main() {
int D;
scanf("%d %d %d %d", &p, &q, &r, &D);
static int v[MAXN + 1][MAXN + 1][MAXN + 1];
for (int k = 1; k <= r; k++) for (int i = 1; i <= p; i++) for (int j = 1; j <= q; j++) scanf("%d", &v[i][j][k]);
const int s = 0, t = p * q * r + 1;
const int d[4][2] = {
{0, 1},
{0, -1},
{1, 0},
{-1, 0}
};
for (int i = 1; i <= p; i++) for (int j = 1; j <= q; j++) {
for (int k = 1; k <= r; k++) {
addEdge(getID(i, j, k - 1), getID(i, j, k), v[i][j][k]);
if (k > D) for (int l = 0; l < 4; l++) {
int x = i + d[l][0], y = j + d[l][1];
if (valid(x, y)) addEdge(getID(i, j, k), getID(x, y, k - D), INT_MAX);
}
}
addEdge(getID(i, j, r), t, INT_MAX);
}
printf("%dn", Dinic::solve(s, t, t + 1));
return 0;
}

[BZOJ 3144][HNOI 2013] 切糕的更多相关文章

  1. 图论(网络流):[HNOI 2013]切糕

    [HNOI 2013]切糕 第三题:切糕(程序文件名:cake.exe)100 分,运行时限:5s 经过千辛万苦小A 得到了一块切糕,切糕的形状是长方体,小A 打算拦腰将切糕切成两半分给小B.出于美观 ...

  2. [HNOI 2013]切糕

    COGS 2398. [HNOI 2013]切糕 http://www.cogs.pro/cogs/problem/problem.php?pid=2398 ★★★☆   输入文件:nutcake.i ...

  3. 【BZOJ 3144】 [Hnoi2013]切糕 真·最小割

    一开始一脸懵逼后来发现,他不就是割吗,我们只要满足条件就割就行了,于是我们把他连了P*Q*R条边,然而我们要怎样限制D呢?我们只要满足对于任意相邻的两条路,只要其有个口大于D就不行就好了因此我们只要把 ...

  4. [BZOJ 3144] [Hnoi2013] 切糕 【最小割】

    题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的 ...

  5. [BZOJ 3144] 切糕

    Link: BZOJ 3144 传送门 Solution: 发现要把点集分成不连通的两部分,最小割的模型还是很明显的 首先我们将原图转化为$R+1$层,从而将点权化为边权 关键还是在于建图是怎么保证$ ...

  6. [BZOJ 3167][HEOI 2013]SAO

    [BZOJ 3167][HEOI 2013]SAO 题意 对一个长度为 \(n\) 的排列作出 \(n-1\) 种限制, 每种限制形如 "\(x\) 在 \(y\) 之前" 或 & ...

  7. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  8. [BZOJ 3173] [TJOI 2013] 最长上升子序列(fhq treap)

    [BZOJ 3173] [TJOI 2013] 最长上升子序列(fhq treap) 题面 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数 ...

  9. BZOJ 3236 AHOI 2013 作业 莫队+树状数组

    BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出     题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...

随机推荐

  1. LaTeX Windows配置

    1. 安装TeXstudio 用搜索引擎找合适的版本或者 在 https://sourceforge.net/projects/texstudio/ 下载 找合适的版本下载,点击下一步安装即可. Te ...

  2. Codeforces 1294E - Obtain a Permutation

    题目大意: 给定一个n*m的矩阵 可以更改任意一个位置的值 也可以选择一整列全部往上移动一位,最上方的数移动到最下方 问最少操作多少次可以把这个矩阵移动成 1 2 3 ... m m+1 m+2 m+ ...

  3. 并发与高并发(二)-JAVA内存模型

    一.java内存模型(JMM)-同步操作与规则 它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式.一个线程如何和何时能看到其他线程共享 ...

  4. Window Redis安装

    1.下载redis 下载地址:https://github.com/MicrosoftArchive/redis/releases ​ 2. 安装redis 把下载的Redis-x64-3.2.100 ...

  5. 蓝桥杯 Car的旅行路线 (预处理+最短路径)

    https://www.luogu.org/problem/P1027 题目描述 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有4个飞机场,分别位于一个矩形的4个顶点上,同 ...

  6. 画一画BeagleboneBlack的PCB

    一直有听说“Cadence是这个星球上第一好用的EDA软件”,便想着找机会来学学.正好BeagleboneBlack是用Cadence设计的,而且是开源硬件,原理图和PCB文件可以直接在Wiki上下载 ...

  7. java select单线程 服务器

    package com.Select; /** *select单线程 服务器 **/ import java.io.IOException; import java.net.InetSocketAdd ...

  8. windowsserver的应用升级部署坑

    jar文件的后缀名要打开显示,否者备份的‘.bak20190820’可能后面还是jar可执行文件,以至于mybatis这类xml映射器的namespace方法重复扫上去导致注册tomcat conte ...

  9. Java中使用PrepateStatement并且like模糊查询

    在使用PreparedStatement进行模糊查询的时候废了一番周折,以前一直都没有注意这个问题.一般情况下我们进行精确查询,sql语句类似:select * from table where na ...

  10. Notes_STL_List_And_Map

    //Description: 使用STL遇到的问题 //Create Date: 2019-07-08 09:19:15 //Author: channy Notes_STL_List_And_Map ...