Luogu P3227 [HNOI2013]切糕
%%ZZKdalao上课讲的题目,才知道网络流的这种玄学建模
我们先想一想,如果没有D的限制,那么想当于再每一根纵轴上选一个权值最小的点再加起来
我们对应在网络流上就是每一根纵轴上的点向它下方的点用权值当边值进行连边,然后要割掉一些边,代价最小就是求最小割
然后我们考虑限制,就是如果割了某一根数轴上高度为x的点,那么所有与它相邻的纵轴都只能割高度为[x-d,x+d]的点
这个时候我们就要知道一个常用技巧:在求最小割时,我们可以把那些无法割去的边边权设为INF
因此我们在建边时,由纵轴上一度为x的点高向与它相邻的纵轴上高度为x-d的点连边,边权为INF
为什么呢,我们结合一个图来看一下:

其中红色的边表示边权为INF,无法割去
当我们选择割掉5-7的这条边时,会发现2-4这条边无法割去。因为就算割去了也可以从5-4这条边过去。这就达到了我们的目的
因此我们这样建边之后跑最大流即可
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=45,INF=1e9,fx[4]={0,1,0,-1},fy[4]={1,0,-1,0};
struct edge
{
int to,next,c;
}e[N*N*N*20];
int v[N][N][N],head[N*N*N],dep[N*N*N],Q[N*N*N],p,q,r,d,s,t,cnt=-1;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline int get_num(int x,int y,int z)
{
return x*p*q+y*q+z;
}
inline void add(int x,int y,int z)
{
e[++cnt].to=y; e[cnt].c=z; e[cnt].next=head[x]; head[x]=cnt;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline bool BFS(void)
{
memset(dep,0,sizeof(dep));
dep[s]=1; Q[1]=s;
int H=0,T=1;
while (H<T)
{
int now=Q[++H];
for (register int i=head[now];i!=-1;i=e[i].next)
if (!dep[e[i].to]&&e[i].c)
{
dep[e[i].to]=dep[now]+1;
Q[++T]=e[i].to;
}
}
return dep[t];
}
inline int DFS(int now,int dist)
{
if (now==t) return dist;
int res=0;
for (register int i=head[now];i!=-1&&dist;i=e[i].next)
if (dep[e[i].to]==dep[now]+1&&e[i].c)
{
int dis=DFS(e[i].to,min(dist,e[i].c));
dist-=dis; res+=dis;
e[i].c-=dis; e[i^1].c+=dis;
}
if (!res) dep[now]=0;
return res;
}
inline int Dinic(void)
{
int res=0;
while (BFS()) res+=DFS(s,INF);
return res;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i,j,k;
memset(e,-1,sizeof(e));
memset(head,-1,sizeof(head));
read(p); read(q); read(r); read(d); s=0; t=get_num(r,p,q)+1;
for (i=1;i<=r;++i)
for (j=1;j<=p;++j)
for (k=1;k<=q;++k)
read(v[i][j][k]);
for (i=1;i<=p;++i)
for (j=1;j<=q;++j)
add(s,get_num(0,i,j),INF),add(get_num(0,i,j),s,0),add(get_num(r,i,j),t,INF),add(t,get_num(r,i,j),0);
for (i=1;i<=r;++i)
for (j=1;j<=p;++j)
for (k=1;k<=q;++k)
add(get_num(i-1,j,k),get_num(i,j,k),v[i][j][k]),add(get_num(i,j,k),get_num(i-1,j,k),0);
for (i=d;i<=r;++i)
for (j=1;j<=p;++j)
for (k=1;k<=q;++k)
for (register int kind=0;kind<4;++kind)
{
int x=j+fx[kind],y=k+fy[kind];
if (x>0&&x<=p&&y>0&&y<=q)
add(get_num(i,j,k),get_num(i-d,x,y),INF),add(get_num(i-d,x,y),get_num(i,j,k),0);
}
printf("%d",Dinic());
return 0;
}
Luogu P3227 [HNOI2013]切糕的更多相关文章
- Luogu P3227 [HNOI2013]切糕 最小割
首先推荐一个写的很好的题解,个人水平有限只能写流水账,还请见谅. 经典的最小割模型,很多人都说这个题是水题,但我还是被卡了=_= 技巧:加边表示限制 在没有距离\(<=d\)的限制时候,我们对每 ...
- P3227 [HNOI2013]切糕
题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案 ...
- [洛谷P3227][HNOI2013]切糕
题目大意:有一个$n\times m$的切糕,每一个位置的高度可以在$[1,k]$之间,每个高度有一个代价,要求四联通的两个格子之间高度最多相差$D$,问可行的最小代价.$n,m,k,D\leqsla ...
- 洛谷 P3227 [HNOI2013]切糕(最小割)
题解 Dinic求最小割 题目其实就是求最小的代价使得每个纵轴被分成两部分 最小割!!! 我们把每个点抽象成一条边,一个纵轴就是一条\(S-T\)的路径 但是题目要求\(|f(x,y)-f(x',y' ...
- 洛谷$P3227\ [HNOI2013]$切糕 网络流
正解:网络流 解题报告: 传送门! 日常看不懂题系列,,,$QAQ$ 所以先放下题目大意趴$QwQ$,就说有个$p\cdot q$的矩阵,每个位置可以填一个$[1,R]$范围内的整数$a_{i,j}$ ...
- bzoj3144 [HNOI2013]切糕(最小割)
bzoj3144 [HNOI2013]切糕(最小割) bzoj Luogu 题面描述见上 题解时间 一开始我真就把这玩意所说的切面当成了平面来做的 事实上只是说相邻的切点高度差都不超过 $ d $ 对 ...
- BZOJ 3144: [Hnoi2013]切糕
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1495 Solved: 819[Submit][Status] ...
- bzoj 3144: [Hnoi2013]切糕 最小割
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 681 Solved: 375[Submit][Status] ...
- BZOJ_3144_[Hnoi2013]切糕_最小割
BZOJ_3144_[Hnoi2013]切糕_最小割 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R ...
随机推荐
- 类与接口(三)java中的接口与嵌套接口
一.接口 1. 接口简介 接口: 是java的一种抽象类型,是抽象方法的集合.接口比抽象类更加抽象的抽象类型. 接口语法: [修饰符] [abstract] interface 接口名 [extend ...
- Visual Studio 2012 Update 1 离线升级包(相当于VS2012 SP1离线补丁包)
Visual Studio 2012 Update 1 发布也有一段时间了,吾乐吧尝试了好几次在线升级,但是网络不给力啊,结果都失败了.于是一直都想找到官方提供的VS2012 SP1完整离线升级包,不 ...
- cuda和gcc版本不兼容
gcc8.1和cuda9.0版本不兼容,比较坑. 下面是各版本cuda支持的gcc: 从CUDA 4.1版本开始,现在支持gcc 4.5.gcc 4.6和4.7不受支持. 从CUDA 5.0版本开始, ...
- ionic插件安装与卸载
使用下面的命令查询.安装.卸载插件: $ ionic plugin list //列出所有已安装插件 $ ionic plugin remove 插件名 //先根据上面的list列出插件,然后根据插件 ...
- .NET中低版本程序调用高版本DLL
在.NET项目开发中,有时需要对旧的程序进行二次开发,但是有些DLL是高版本的,如果对旧程序升级高版本,则需要改动的地方比较多,在项目比较急,开发时间短的情况下,可以通过下面方法让低版本程序调用高版本 ...
- Oracle EBS INV更新保留
CREATE or REPPLACE PROCEDURE UpdateReservation AS -- Common Declarations l_api_version NUMBER := 1.0 ...
- JBoss 7 里一个EJB依赖其他jar的几种方式
JBoss 7 与之前的版本有了巨大的变化,最核心的类的加载方式变了,有点类似OSGI那样搞起来了分模块的类加载方式,而不是以前的分层类加载.按以前的类加载方式,在加载树底下的那些类,总是能看到父节点 ...
- ngrep命令用法
ngrep 是grep(在文本中搜索字符串的工具)的网络版,他力求更多的grep特征,用于搜寻指定的数据包.正由于安装ngrep需用到libpcap库, 所以支持大量的操作系统和网络协议.能识别TCP ...
- mySQL 约束 (Constraints)
约束用于限制加入表的数据的类型: 1.创建表时规定约束(通过 CREATE TABLE 语句) 2.表创建之后也可以(通过 ALTER TABLE 语句). 约束类型: NOT NULL(非空) UN ...
- 一个汇编的HelloWorld!
花了一下午时间,感觉最坑的是,书写代码的个数和编译器的坑比较多,还各种版本的编译器! 会让人“眼花缭乱”! 主要代码 将文件保存为*.asm include io32.inc .data ;数据 sr ...