BZOJ3144:[HNOI2013]切糕——题解
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]切糕——题解的更多相关文章
- bzoj3144 [HNOI2013]切糕(最小割)
bzoj3144 [HNOI2013]切糕(最小割) bzoj Luogu 题面描述见上 题解时间 一开始我真就把这玩意所说的切面当成了平面来做的 事实上只是说相邻的切点高度差都不超过 $ d $ 对 ...
- BZOJ3144 Hnoi2013 切糕 【网络流】*
BZOJ3144 Hnoi2013 切糕 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的 ...
- bzoj千题计划142:bzoj3144: [Hnoi2013]切糕
http://www.lydsy.com/JudgeOnline/problem.php?id=3144 如果D=2 ,两个点,高度为4,建图如下 #include<queue> #inc ...
- BZOJ3144 [Hnoi2013]切糕 【最小割】
题目 输入格式 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...
- Bzoj3144 [Hnoi2013]切糕
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1494 Solved: 818 Description Input 第一行是三个正整数P,Q,R,表 ...
- BZOJ3144[Hnoi2013]切糕——最小割
题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...
- [BZOJ3144][HNOI2013]切糕(最小割)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3144 分析:神题不解释 http://www.cnblogs.com/zig-zag/ ...
- 【BZOJ3144】[HNOI2013]切糕
[BZOJ3144][HNOI2013]切糕 题面 题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑 ...
- 【BZOJ3144】[Hnoi2013]切糕 最小割
[BZOJ3144][Hnoi2013]切糕 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q ...
随机推荐
- JS dataTables
原文地址: http://www.cnblogs.com/haogj/archive/2011/03/04/1971328.html 数据来源有四种: 1. 网页DOM对象 $(document) ...
- hdu1058Humble Numbers(动态规划)
Humble Numbers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- JSP学习(JavaBean)
Java Web学习 一.搭建java web开发环境: (1)安装jdk (2)安装Tomcat服务器(Apache的开源项目),安装Tomcat并设置环境变量 (3)安装EclipseEE(或者M ...
- 内置方法(item系列)
class Foo: def __init__(self,name): self.name = name def __getitem__(self, item): # 获取时触发 print('get ...
- vim基本命令笔记
两种模式 -编辑模式:可以进行正常的编辑操作 左下方显示 -- INSERT -- "在命令模式下输入 i 能够进入编辑模式" -命令模式:可以通过命令 左下方什么也不显示 &qu ...
- HADOOP-输出数据实体类承载
新建一个bean包: 1.实现Writerable 2.有一个空的构造方法 代码实现: import java.io.DataInput; import java.io.DataOutput; imp ...
- 最小生成树与Prim算法
最小生成树(MST) 定义 首先是一棵树(废话 其次没有回路(废话 包含全部顶点和V-1条边 边的权重和最小!!!!! 所以如果是单棵最小生成树,至少说明图是连通的.不然就是森林. 生成思路 既然是根 ...
- Python 学习笔记之——用 sklearn 对数据进行预处理
1. 标准化 标准化是为了让数据服从一个零均值和单位方差的标准正态分布.也即针对一个均值为 \(mean\) 标准差为 \(std\) 的向量 \(X\) 中的每个值 \(x\),有 \(x_{sca ...
- Icingaweb2监控oracle数据库的安装配置流程
Icinga2安装配置check_oracle_health流程 1.安装 由于check_oracle_health是使用perl语言编写的,因此在安装该插件之前,首先要安装oracle的客户端实例 ...
- “Hello World!”团队第二次会议
今天是我们团队“hello world!”团队召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 20 ...
