题目大意:有一个$n\times m$的切糕,每一个位置的高度可以在$[1,k]$之间,每个高度有一个代价,要求四联通的两个格子之间高度最多相差$D$,问可行的最小代价。$n,m,k,D\leqslant 40$

题解:网络流,不考虑相差为$D$的条件时,可以给每个位置建一个点,源点连向高度为$1$的点容量为$\infty$,高度为$i$的点连向这个位置高度为$i+1$的点,容量为代价,高度为$k$的连向汇点,容量为代价。跑最小割。

考虑相差为$D$的条件,可以对于相邻的两个点$A,B$,连接$A_i\to B_{i-D}$的容量为$\infty$的边这样就强制限定两个点的最小割必须相距小于等于$D$,跑最小割即可

卡点:加边的时候多加了$k$倍,导致又$TLE$又$RE$

C++ Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
const int inf = 0x3f3f3f3f; namespace std {
struct istream {
#define M (1 << 24 | 3)
char buf[M], *ch = buf - 1;
inline istream() { fread(buf, 1, M, stdin); }
inline istream& operator >> (int &x) {
while (isspace(*++ch));
for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
return *this;
}
#undef M
} cin;
struct ostream {
#define M (1 << 10 | 3)
char buf[M], *ch = buf - 1;
inline ostream& operator << (int x) {
if (!x) {*++ch = '0'; return *this;}
static int S[20], *top; top = S;
while (x) {*++top = x % 10 ^ 48; x /= 10;}
for (; top != S; --top) *++ch = *top;
return *this;
}
inline ostream& operator << (const char x) {*++ch = x; return *this;}
inline ~ostream() { fwrite(buf, 1, ch - buf + 1, stdout); }
#undef M
} cout;
} namespace Network_Flow {
const int maxn = 50 * 50 * 50, maxm = maxn * 6; int lst[maxn], head[maxn], cnt = 1;
struct Edge {
int to, nxt, w;
} e[maxm << 1];
void addedge(int a, int b, int c) {
e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
e[++cnt] = (Edge) { a, head[b], 0 }; head[b] = cnt;
} int st, ed, n, MF;
int GAP[maxn], dis[maxn], q[maxn], h, t;
void init() {
GAP[dis[q[h = t = 0] = ed] = 1] = 1;
for (int i = st; i <= ed; ++i) lst[i] = head[i];
while (h <= t) {
int u = q[h++];
for (int i = head[u], v; i; i = e[i].nxt) {
v = e[i].to;
if (!dis[v]) {
++GAP[dis[v] = dis[u] + 1];
q[++t] = v;
}
}
}
}
int dfs(int u, int low) {
if (!low || u == ed) return low;
int w, res = 0;
for (int &i = lst[u], v; i; i = e[i].nxt) if (e[i].w) {
v = e[i].to;
if (dis[u] == dis[v] + 1) {
w = dfs(v, std::min(low, e[i].w));
res += w, low -= w;
e[i].w -= w, e[i ^ 1].w += w;
if (!low) return res;
}
}
if (!--GAP[dis[u]]) dis[st] = n + 1;
++GAP[++dis[u]], lst[u] = head[u];
return res;
}
void ISAP(int S, int T) {
st = S, ed = T, n = T - S + 1;
init(); while (dis[st] <= n) MF += dfs(st, inf);
}
} int n, m, h, D;
int v[50][50][50];
int pos[50][50][50], idx, st, ed; void addedge(int x, int y, int z, int w) {
for (int i = D + 1; i <= h; ++i)
Network_Flow::addedge(pos[x][y][i], pos[z][w][i - D], inf);
}
int main() {
std::cin >> n >> m >> h >> D;
for (int i = 1; i <= h; ++i)
for (int j = 1; j <= n; ++j)
for (int k = 1; k <= m; ++k) {
pos[j][k][i] = ++idx;
std::cin >> v[j][k][i];
}
st = 0, ed = ++idx;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
for (int k = 1; k <= h; ++k) {
if (k == 1) Network_Flow::addedge(st, pos[i][j][k], inf);
if (k == h) Network_Flow::addedge(pos[i][j][k], ed, v[i][j][k]);
else Network_Flow::addedge(pos[i][j][k], pos[i][j][k + 1], v[i][j][k]);
}
if (i != 1) addedge(i, j, i - 1, j);
if (i != n) addedge(i, j, i + 1, j);
if (j != 1) addedge(i, j, i, j - 1);
if (j != n) addedge(i, j, i, j + 1);
}
Network_Flow::ISAP(st, ed);
std::cout << Network_Flow::MF << '\n';
return 0;
}

  

[洛谷P3227][HNOI2013]切糕的更多相关文章

  1. 洛谷 P3227 [HNOI2013]切糕(最小割)

    题解 Dinic求最小割 题目其实就是求最小的代价使得每个纵轴被分成两部分 最小割!!! 我们把每个点抽象成一条边,一个纵轴就是一条\(S-T\)的路径 但是题目要求\(|f(x,y)-f(x',y' ...

  2. 洛谷$P3227\ [HNOI2013]$切糕 网络流

    正解:网络流 解题报告: 传送门! 日常看不懂题系列,,,$QAQ$ 所以先放下题目大意趴$QwQ$,就说有个$p\cdot q$的矩阵,每个位置可以填一个$[1,R]$范围内的整数$a_{i,j}$ ...

  3. 洛谷 P3227 BZOJ 3144 [HNOI2013]切糕

    题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案 ...

  4. [洛谷P3228] [HNOI2013]数列

    洛谷题目链接:[HNOI2013]数列 题目描述 小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨.股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N.在疯涨的K天中小T观察到: ...

  5. P3227 [HNOI2013]切糕

    题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案 ...

  6. 【洛谷 P3227】 [HNOI2013]切糕(最小割)

    题目链接 每层每个位置向下一层这个位置连边,流量为下一层这个位置的\(f\),源点向第一层连,流量第一层每个位置的费用,最后一层向汇点连,流量\(INF\). 这样就得到了\(P*Q\)条链,不考虑\ ...

  7. 洛谷P3227 切糕

    最小割模板. 题意:你要在一个三维点阵的每个竖条中删去一个点,使得删去的点权和最小. 且相邻(四联通)的两竖条之间删的点的z坐标之差的绝对值不超过D. 解: 首先把这些都串起来,点边转化,就变成最小割 ...

  8. Luogu P3227 [HNOI2013]切糕 最小割

    首先推荐一个写的很好的题解,个人水平有限只能写流水账,还请见谅. 经典的最小割模型,很多人都说这个题是水题,但我还是被卡了=_= 技巧:加边表示限制 在没有距离\(<=d\)的限制时候,我们对每 ...

  9. Luogu P3227 [HNOI2013]切糕

    %%ZZKdalao上课讲的题目,才知道网络流的这种玄学建模 我们先想一想,如果没有D的限制,那么想当于再每一根纵轴上选一个权值最小的点再加起来 我们对应在网络流上就是每一根纵轴上的点向它下方的点用权 ...

随机推荐

  1. 在Modelsim波形窗口复制信号

    可以通过张贴复制变量名在Modelsim波形窗口复制信号.

  2. 用gmsh做前处理

    原视频下载地址:  https://pan.baidu.com/s/1i4Y9fbJ  密码: 7rkb

  3. 各种系统性能优化技术,采用vilocity实现商品页面静态化

    1.大型门户网站系统:>10万的访问量   行业网站(当当网,卓越网):20万-30万,一个小时内会跟数据库的交互至少20万-30万,会产生数据库瓶颈,每个数据库都有一个最大连接数(socket ...

  4. [RoarCTF]Easy Java

    目录 [RoarCTF]Easy Java 知识点 1.WEB-INF/web.xml泄露 [RoarCTF]Easy Java 题目复现链接:https://buuoj.cn/challenges ...

  5. 解决idea创建Maven项目速度慢

    idea在创建maven项目的时候会去网上自动下载需要的插件,这样就会导致项目创建后一直处于下载插件的状态中,影响开发效率 此时我们可以在创建maven骨架的时候,加入键值对来让maven调用本地的骨 ...

  6. Systemback制作大于4G的Ubuntu系统镜像

    1 安装Systemback 依此执行如下命令. sudo apt-get update sudo add-apt-repository ppa:nemh/systemback sudo apt-ge ...

  7. Predictive Analysis in Network Function Virtualization

    摘要 网络功能虚拟化(NFV)体系结构的最新部署获得了极大的关注.虚拟化虽然带来了诸如降低成本和简化网络功能部署之类的好处,但它增加了附加层,从而降低了较低层故障的透明度.为了改善虚拟网络功能(VNF ...

  8. 第05组Alpha冲刺(1/4)

    队名:天码行空 组长博客连接 作业博客连接 团队燃尽图(共享): GitHub当日代码/文档签入记录展示(共享): 组员情况: 组员1:卢欢(组长) 过去两天完成了哪些任务:SVN管理工具搭建 展示G ...

  9. 【软工实践】Beta冲刺(5/5)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...

  10. skywalking安装运行(docker)

    https://github.com/apache/skywalking-docker/tree/master/6/6.5 https://hub.docker.com/r/apache/skywal ...