题目描述

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

出于简便考虑,我们将切糕视作一个长 P、宽 Q、高 R 的长方体点阵。我们将位于第 z层中第 x 行、第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z)。一个合法的切面满足以下两个条件:

  1. 与每个纵轴(一共有 P*Q 个纵轴)有且仅有一个交点。即切面是一个函数 f(x,y),对于所有 1≤x≤P, 1≤y≤Q,我们需指定一个切割点 f(x,y),且 1≤f(x,y)≤R。

  2. 切面需要满足一定的光滑性要求,即相邻纵轴上的切割点不能相距太远。对于所有的 1≤x,x’≤P 和 1≤y,y’≤Q,若|x-x’|+|y-y’|=1,则|f(x,y)-f(x’,y’)| ≤D,其中 D 是给定的一个非负整数。 可能有许多切面f 满足上面的条件,小A 希望找出总的切割点上的不和谐值最小的那个。

输入输出格式

输入格式:

第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1<=x<=P, 1<=y<=Q, 1<=z<=R)。 100%的数据满足P,Q,R<=40,0<=D<=R,且给出的所有的不和谐值不超过1000。

输出格式:

仅包含一个整数,表示在合法基础上最小的总不和谐值。

输入输出样例

输入样例#1:

2  2 2
1
6 1
6 1
2 6
2 6
输出样例#1:

6

说明

最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1

我们将点转化成边,那么选点就等于割边,第一个条件满足

对于第二个条件我们可以用一些inf的边来"屏蔽"那些不能割的边,从z向"相邻的"路径的z-d号点连inf的边(如上图)这样做之后,如果删了这条边,我们还可以通过这些桥梁,从相邻的路径的一段[z-d,z+d]绕过,所以割那些边就没有意义了

从而实现必须割[z-d,z+d]的目的

来源:洛谷题解

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN=;
const int INF = 1e8;
inline void read(int &n)
{
char c='+';int x=;bool flag=;
while(c<''||c>''){c=getchar();if(c=='-')flag=;}
while(c>=''&&c<=''){x=x*+c-;c=getchar();}
n=flag==?-x:x;
}
int n,m,s,t;
struct node
{
int u,v,flow,nxt;
}edge[MAXN];
int head[MAXN];
int cur[MAXN];
int num=;
int deep[MAXN];
int tot=;
void add_edge(int x,int y,int z)
{
edge[num].u=x;
edge[num].v=y;
edge[num].flow=z;
edge[num].nxt=head[x];
head[x]=num++;
}
void add(int x,int y,int z)
{
add_edge(x,y,z);
add_edge(y,x,);
}
bool BFS()
{
memset(deep,,sizeof(deep));
deep[s]=;
queue<int>q;
q.push(s);
while(q.size()!=)
{
int p=q.front();
q.pop();
for(int i=head[p];i!=-;i=edge[i].nxt)
if(!deep[edge[i].v]&&edge[i].flow)
deep[edge[i].v]=deep[edge[i].u]+,
q.push(edge[i].v);
}
return deep[t]; }
int DFS(int now,int nowflow)
{
if(now==t||nowflow<=)
return nowflow;
int totflow=;
for(int &i=cur[now];i!=-;i=edge[i].nxt)
{
if(deep[edge[i].v]==deep[edge[i].u]+&&edge[i].flow)
{
int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow));
edge[i].flow-=canflow;
edge[i^].flow+=canflow;
totflow+=canflow;
nowflow-=canflow;
if(nowflow<=)
break;
} }
return totflow;
}
void Dinic()
{
int ans=;
while(BFS())
{
memcpy(cur,head,MAXN);
ans+=DFS(s,1e8);
}
printf("%d",ans);
}
int a[][][];
int cnt=;
int xx[]={-,+,,};
int yy[]={,,-,+};
int main()
{
memset(head,-,sizeof(head));
int P,Q,R,D;
read(P);read(Q);read(R);read(D);
for(int i=;i<=R+;i++)
for(int j=;j<=P;j++)
for(int k=;k<=Q;k++)
a[i][j][k]=++cnt;
s=;t=cnt+;
for(int i=;i<=P;i++)
for(int j=;j<=Q;j++)
{
add(s,a[][i][j],INF);
add(a[R+][i][j],t,INF);//上下界
}
for(int i=;i<=R;i++)
for(int j=;j<=P;j++)
for(int k=;k<=Q;k++)
{
int p;read(p);
add(a[i][j][k],a[i+][j][k],p);
}// 连边
for(int i=D+;i<=R;i++)
for(int j=;j<=P;j++)
for(int k=;k<=Q;k++)
for(int m=;m<;m++)
if(a[i-D][j+xx[m]][k+yy[m]]>)
add(a[i][j][k],a[i-D][j+xx[m]][k+yy[m]],INF);
//for(int i=1;i<=num-1;i++)
//printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].flow);
Dinic();
return ;
}

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

  1. [洛谷P3227][HNOI2013]切糕

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

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

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

  3. Luogu P3227 [HNOI2013]切糕

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

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

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

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

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

  6. BZOJ 3144: [Hnoi2013]切糕

    3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1495  Solved: 819[Submit][Status] ...

  7. bzoj 3144: [Hnoi2013]切糕 最小割

    3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 681  Solved: 375[Submit][Status] ...

  8. BZOJ_3144_[Hnoi2013]切糕_最小割

    BZOJ_3144_[Hnoi2013]切糕_最小割 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R ...

  9. bzoj千题计划142:bzoj3144: [Hnoi2013]切糕

    http://www.lydsy.com/JudgeOnline/problem.php?id=3144 如果D=2 ,两个点,高度为4,建图如下 #include<queue> #inc ...

随机推荐

  1. Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字

    题目链接:点击打开链接 每一个点都是最大值,把一整个序列和都压缩在一个点里. 1.普通的区间求和就是维护2个值,区间和Sum和延迟标志Lazy 2.Old 是该区间里出现过最大的Sum, Oldlaz ...

  2. 【Java】【Flume】Flume-NG启动过程源代码分析(一)

    从bin/flume 这个shell脚本能够看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在. main方法首先会先解析sh ...

  3. Under ubuntu 12.04,install sublime text 2

    Sublime Text is an awesome text editor. If you’ve never heard of it, you should check it out right n ...

  4. 关于输入getline

    此函数可读取整行,包括前导和嵌入的空格,并将其存储在字符串对象中. getline 函数如下所示: getline(cin, inputLine); 其中 cin 是正在读取的输入流,而 inputL ...

  5. xBIM 基础07 创建WebBIM文件

    系列目录    [已更新最新开发文章,点击查看详细]  xBIM项目提供了一个IFC文件的Web查看器.当你想把IFC转换成紧凑的WexBIM时,需要 xBIM Essentials 和 xBIM G ...

  6. App.config配置详解

    经上一篇文章https://www.cnblogs.com/luna-hehe/p/9104701.html发现自己对配置文件很是不了解,同样还是查了半天终于发现另一片宝贵文档https://www. ...

  7. WPF XAML

    xmlns 在xml中专门用于声明名字控件, xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 是 ...

  8. 004.ES2015和ES2016新特性--块级作用域变量

    其基本原理就是JavaScript的作用域链,下面以对比的方式来展示一下函数级作用域和块级作用域. 函数级作用域 var fns = []; for (var i = 0; i < 5 ; i+ ...

  9. 【原创】Google的文本内容对比代码

    /* * Diff Match and Patch * * Copyright 2006 Google Inc. * http://code.google.com/p/google-diff-matc ...

  10. 50个极好的bootstrap框架

    转自:http://sudasuta.com/bootstrap-admin-templates.html  https://www.cnblogs.com/sanhao/p/9184323.html ...