https://www.lydsy.com/JudgeOnline/problem.php?id=3144

看着很像网络流,但是费用流貌似无法解决这个问题,其实甚至连忽略d的情况都做不到。

最小割?

将顶层和底层分成两个集合,切一次就相当于两个集合分开。

所以我们(i,j,k)->(i,j,k+1)边权为val(i,j,k)就可以做忽略d的情况了。

那么有d也很简单,只需要想你切完了一条边之后,不能让你身边的切哪些边即可。

画个图,我们就能发现(i,j,k)->(i,j,k-d)和(i,j,k+d+1)->(i,j,k+1)边权为INF就能保证如果切了非法的边仍然能保证连通。

(当然在遍历的时候后者的边也是前者的边,于是我们只需要加前者的边即可。)

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int B=;
const int N=B*B*B+B*B;
const int M=N*;
const int INF=1e9;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt,w;
}e[M];
int P,Q,R,D,cnt,head[N],cur[N],lev[N];
int val[B][B][B],dui[N],r,S,T;
int dx[]={,,,-};
int dy[]={,,-,};
inline void add(int u,int v,int w){
e[++cnt].to=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
}
bool bfs(int m){
for(int i=;i<=m;i++){
cur[i]=head[i];lev[i]=-;
}
lev[S]=;dui[r=]=S;
for(int l=;l<=r;l++){
int u=dui[l];
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(e[i].w&&lev[v]==-){
dui[++r]=v;
lev[v]=lev[u]+;
if(v==T)return ;
}
}
}
return ;
}
int dinic(int u,int flow,int m){
if(u==m)return flow;
int res=,delta;
for(int &i=cur[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(lev[v]>lev[u]&&e[i].w){
delta=dinic(v,min(flow-res,e[i].w),m);
if(delta){
res+=delta;
e[i].w-=delta;
e[i^].w+=delta;
if(res==flow)break;
}
}
}
if(res!=flow)lev[u]=-;
return res;
}
inline int num(int i,int j,int k){
return (k-)*P*Q+(i-)*Q+j;
}
int main(){
cnt=-;memset(head,-,sizeof(head));
P=read(),Q=read(),R=read();
D=read();
S=(R+)*P*Q+,T=S+;
for(int k=;k<=R;k++)
for(int i=;i<=P;i++)
for(int j=;j<=Q;j++){
int u=num(i,j,k),v=num(i,j,k+);
add(u,v,read());add(v,u,);
if(k>D)
for(int l=;l<;l++){
int nx=i+dx[l],ny=j+dy[l];
if(nx<||nx>P||ny<||ny>Q)continue;
int nv=num(nx,ny,k-D);
add(u,nv,INF);add(nv,u,);
}
}
for(int i=;i<=P;i++)
for(int j=;j<=Q;j++){
int v=num(i,j,),u=num(i,j,R+);
add(S,v,INF);add(v,S,);
add(u,T,INF);add(T,u,);
}
int ans=;
while(bfs(T))ans+=dinic(S,INF,T);
printf("%d\n",ans);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ3144:[HNOI2013]切糕——题解的更多相关文章

  1. bzoj3144 [HNOI2013]切糕(最小割)

    bzoj3144 [HNOI2013]切糕(最小割) bzoj Luogu 题面描述见上 题解时间 一开始我真就把这玩意所说的切面当成了平面来做的 事实上只是说相邻的切点高度差都不超过 $ d $ 对 ...

  2. BZOJ3144 Hnoi2013 切糕 【网络流】*

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

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

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

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

    题目 输入格式 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...

  5. Bzoj3144 [Hnoi2013]切糕

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1494  Solved: 818 Description Input 第一行是三个正整数P,Q,R,表 ...

  6. BZOJ3144[Hnoi2013]切糕——最小割

    题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...

  7. [BZOJ3144][HNOI2013]切糕(最小割)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3144 分析:神题不解释 http://www.cnblogs.com/zig-zag/ ...

  8. 【BZOJ3144】[HNOI2013]切糕

    [BZOJ3144][HNOI2013]切糕 题面 题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑 ...

  9. 【BZOJ3144】[Hnoi2013]切糕 最小割

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

随机推荐

  1. 鸡啄米:C++编程之十三学习之类与对象,类的声明,成员的访问控制

    1. 本次学习鸡啄米课程第13篇,把比较重要的学习记录下来,以敦促自己更好的学习.推荐他们的网址学习:http://www.jizhuomi.com/school/c/97.html 2. 在面向过程 ...

  2. Mac brew安装redis

    1.安装redis $ brew install redis Error:Failed to download resource "reds"  // 下载reds失败 不过不需要 ...

  3. PHP MySQL 安全方案

     1 转义与清除转义 // 对 用户提交的数据 ' " \ 进行转义 if ( get_magic_quotes_gpc() ) { function del_magic_quotes($v ...

  4. TraceHelper

    public class TraceHelper { private static TraceHelper _traceHelper; private TraceHelper() { } public ...

  5. Python :编写条件分支代码的技巧

    『Python 工匠』是什么? 我一直觉得编程某种意义是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目. 在雕琢代码的过程中,有大工程:比如应该用什么架构.哪种设计模式.也有 ...

  6. [CF19B]Checkout Assistant

    题目描述 Bob 来到一家现购自运商店,将 n 件商品放入了他的手推车,然后到收银台 付款.每件商品由它的价格 pi 和收银员扫描它的时间 ti 秒定义.当收银员正在扫 描某件商品时,Bob 可以从他 ...

  7. java length属性、length()、size()

    length属性 length是属性,用于说明数组的长度. String []list={"wo","shi","shuaibi"}; Sy ...

  8. tendermint学习

    怎么把两个节点变成验证节点 1. 两个节点分别启动 2. 两个节点同时把自己的公钥信息添加到对方的创始快配置文件中,总而言之,创始块一样 3. unsafe_reset_priv_validator ...

  9. 安装HIVE

    参考:https://cwiki.apache.org/confluence/display/Hive/GettingStarted 1.下载hive安装包     到apache官网或者其它地方下载 ...

  10. centos环境配置(nginx,node.js,mysql)

    1.安装 Install GCC and Development Tools on a CentOS yum group install "Development Tools" n ...