[HNOI2013]切糕
题目描述
网址:https://daniu.luogu.org/problemnew/show/3227
大意:
平面上有一长方体,目标为将其切割为上下两半。
切割点为\((x,y,z)\)的点,每个点有一个不和谐值v,现在有两个要求:
- [1]任何两个平面相邻的切割点之间的高度差不能超过D
- [2]要使得最终的不和谐值最小。
求解最小的$ ∑vi $
题目解法
直接建图,化点为边。将最下面的点与S相连,最上面的与T相连。
然后跑最小割即为答案。
现在关键在于如何限制高度差不超过D。
以\((x,y,z)\)与\((x+1,y,z)\)为例。
建立\((x,y,z) —>(x+1,y,z-D)\) 与 \((x+1,y,z+D+1)—>(x,y,z+1)\)两条边
那么在割断\((x,y,z)->(x,y,z+1)\)时,就可保证\((x+1,y)\)上割的为题目所限制范围。
动手画一下就明白了。 如果割超出范围的边,S、T依旧联通。
所以用上述方法建图,然后跑最小割即可得到答案。
实现代码
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#define ll long long
#define RG register
#define IL inline
#define maxn 125000
#define INF 1e16+7
using namespace std;
IL ll gi(){
RG ll date = 0, m = 1; RG char ch = 0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch = getchar();
if(ch == '-'){m = -1; ch = getchar();}
while(ch>='0' && ch<='9')
{date=date*10+ch-'0'; ch = getchar();}
return date*m;
}
ll cnt,Q,P,R,S,T,D;
ll vis[maxn],dep[maxn],head[maxn],cur[maxn];
ll mx[4] = {0,0,-1,1},my[4] = {-1,1,0,0};
struct Road { ll to,next,cap,flow; }t[20*maxn];
IL bool Bfs(){
for(RG ll i = 0; i <= T; i ++)vis[i] = 0;
dep[S] = 0; vis[S] = 1; queue<ll>Que; Que.push(S);
while(!Que.empty()){
RG ll u = Que.front(); Que.pop();
for(RG ll i = head[u]; i!= -1; i = t[i].next){
RG ll v = t[i].to;
if(!vis[v] && t[i].cap > t[i].flow){
dep[v] = dep[u] + 1;
vis[v] = true; Que.push(v);
}
}
}return vis[T];
}
int Dfs(RG ll u,RG ll Lim){
if(u == T || Lim == 0)return Lim;
RG ll flow =0,f = 0;
for(RG ll &i = cur[u]; i != -1; i = t[i].next){
RG ll v = t[i].to;
if(dep[v] == dep[u] + 1 && (f = Dfs(v,min(Lim,t[i].cap-t[i].flow))) > 0){
flow += f; Lim -= f;
t[i].flow += f; t[(i^1)].flow -= f;
if(Lim == 0)break;
}
}return flow;
}
IL int Dinic(){
RG ll Flow = 0;
while(Bfs()){
for(RG ll i = 0; i <= T; i ++)cur[i] = head[i];
Flow += Dfs(S,INF);
}return Flow;
}
IL ll Cod(RG ll z,RG ll x,RG ll y){
return z*(P*Q) + (x-1)*Q + y;
}
IL void Add(ll uu,ll vv,ll cc){
t[cnt++] = (Road){vv,head[uu],cc,0}; head[uu] = cnt - 1;
t[cnt++] = (Road){uu,head[vv],0,0}; head[vv] = cnt - 1;
}
int main(){
freopen("testdate.in","r",stdin);
P = gi(); Q = gi(); R = gi(); D = gi();
S = 0; T = R*P*Q+P*Q+1;
for(RG ll i = 0; i <= T; i ++)head[i] = -1;
for(RG ll h = 1; h <= R; h ++)
for(RG ll i = 1; i <= P; i ++)
for(RG ll j = 1; j <= Q; j ++)
Add( Cod(h,i,j) , Cod(h-1,i,j) , gi());
for(RG ll i = 1; i <= P; i ++)
for(RG ll j = 1; j <= Q; j ++)
Add(Cod(0,i,j),T,INF);
for(RG ll i = 1; i <= P; i ++)
for(RG ll j = 1; j <= Q; j ++)
Add(S,Cod(R,i,j),INF);
for(RG ll h = 1; h <= R; h ++)
for(RG ll i = 1; i <= P; i ++)
for(RG ll j = 1; j <= Q; j ++)
for(RG ll f = 0; f < 4; f ++){
RG int x = mx[f]+i,y = my[f]+j;
if(x<1||y<1||x>P||y>Q)continue;
if(h-D>=0)Add(Cod(h-D,x,y),Cod(h,i,j),INF);
if(h+D<=R)Add(Cod(h,i,j),Cod(h+D,x,y),INF);
}
RG ll Ans = Dinic(); printf("%lld",Ans);
return 0;
}
[HNOI2013]切糕的更多相关文章
- 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 ...
- bzoj千题计划142:bzoj3144: [Hnoi2013]切糕
http://www.lydsy.com/JudgeOnline/problem.php?id=3144 如果D=2 ,两个点,高度为4,建图如下 #include<queue> #inc ...
- 【BZOJ3144】[HNOI2013]切糕
[BZOJ3144][HNOI2013]切糕 题面 题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑 ...
- 【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1764 Solved: 965 Description Inp ...
- BZOJ3144 Hnoi2013 切糕 【网络流】*
BZOJ3144 Hnoi2013 切糕 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的 ...
- 【BZOJ3144】[Hnoi2013]切糕 最小割
[BZOJ3144][Hnoi2013]切糕 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q ...
- 3144: [Hnoi2013]切糕
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1526 Solved: 827[Submit][Status] ...
- bzoj3144 [HNOI2013]切糕(最小割)
bzoj3144 [HNOI2013]切糕(最小割) bzoj Luogu 题面描述见上 题解时间 一开始我真就把这玩意所说的切面当成了平面来做的 事实上只是说相邻的切点高度差都不超过 $ d $ 对 ...
随机推荐
- Maven编译问题
Maven构建的Project默认使用JDK1.5进行编译,要想使用JDK1.8进行编译,最好在项目的POM文件中加上以下的字段. <build> <plugins> < ...
- GitHub入门与实践
基本命令 git status 工作区状态 git add git commint 暂存区 git push gitHub客户端 下载网址:https://desktop.github.com/ 解决 ...
- 自己制作ssl证书:自己签发免费ssl证书,为nginx生成自签名ssl证书
这里说下Linux 系统怎么通过openssl命令生成 证书. 首先执行如下命令生成一个key openssl genrsa -des3 -out ssl.key 1024 然后他会要求你输入这个ke ...
- Linux下配置SNAT上网
局域网有一台主机A,没有公网的IP, 也就是没有办法直接连到互联网上下载东西,同时内网有另外一台主机B,有公网接入.这个时候为了让A连接到互联网,我把B设置成NAT主机,A的网关指向B.准确的来说,现 ...
- linux下双网卡的绑定
如果服务器上有两快网卡就可以把它绑定为一块虚拟的网卡,如果一块网卡坏了另一块还可以继续工作,增加了冗余度和负载,具体做法如下: 新建一个虚拟的网卡,命令如下: iv /etc/sysconfig/ne ...
- PHP 变量的实现原理
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica } p.p2 { margin: 0.0px 0.0px 0.0px 0. ...
- 在windows端和linux端安装Git
一.Git的安装 1. 在windows端 到地址:https://git-scm.com/downloads 选择对应版本下载后,进行傻瓜式安装即可 2. 在linux端 查看是否安装了git,出 ...
- Windows系统上FFMpeg-PHP的使用
这几天做项目,其中一个需求是用户上传视频文件到服务器,然后服务器自动截取该视频的一帧作为该视频对应的缩略图,服务器端语言采用php编写,找了半天资料,发现ffmpeg-php可以满足该需求,所以下面简 ...
- 又是一个愚蠢的错误,皆因.xml而起
论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...
- ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)
前面文章介绍了ASP.NET MVC中的模型绑定和验证功能,本着ASP.NET MVC没有魔法的精神,本章内容将从代码的角度对ASP.NET MVC如何完成模型的绑定和验证进行分析,已了解其原理. 本 ...