题目描述

网址: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]切糕的更多相关文章

  1. BZOJ 3144: [Hnoi2013]切糕

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

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

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

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

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

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

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

  5. 【BZOJ3144】[HNOI2013]切糕

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

  6. 【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)

    3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1764  Solved: 965 Description Inp ...

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

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

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

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

  9. 3144: [Hnoi2013]切糕

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

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

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

随机推荐

  1. 使用Spring Boot搭建应用开发框架(一) —— 基础架构

    Spring的简史 第一阶段:XML配置,在Spring1.x时代,使用Spring开发满眼都是xml配置的Bean,随着项目的扩大,我们需要把xml配置文件分放到不同的配置文件里,那时候需要频繁的在 ...

  2. Redis 持久化和配置文件

    Reids 持久化 Redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File).   RDB,简而言之,就是在不同的时间点,将redis ...

  3. CSS布局(一) 盒子模型

    一.盒子模型 标准盒子模型 从下图可以看到标准 w3c 盒子模型的范围包括 content.padding.border.margin,并且 content 部分不包含其他部分. 怪异盒子模型 从下图 ...

  4. 阿里云Aliyun_server

    一.云概念 云主机是基于云计算平台的一种虚拟的主机服务器产品 云服务器(99.999%安全性,扩展性) 特点: 1.资源分配配置灵活,安全性能强. 2.优于VPS和独立服务器产品.通俗的理解: 云主机 ...

  5. w !sudo tee %

    w !sudo tee % 该命令可用于保存有权限的写文件

  6. shiro整合ehcache

    目标:让Shiro整合ehcache,提供缓存realm数据的功能. 1.引入encache配置文件,配置缓存 <!-- <ehcache xmlns:xsi="http://w ...

  7. Zookeeper笔记3——原理及其安装使用

    Zookeeper到底能干什么? 1.配置管理:这个好理解.分布式系统都有好多机器,Zookeeper提供了这样的一种服务:一种集中管理配置的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣 ...

  8. 搜索引擎的缓存(cache)机制

    什么是缓存? 在搜索领域中,所谓缓存,就是在高速内存硬件设备上为搜索引擎开辟一块存储区,来存储常见的用户查询及其结果,并采用一定的管理策略来维护缓存区内的数据.当搜索引擎再次接收到用户的查询请求时,首 ...

  9. NLP︱LDA主题模型的应用难题、使用心得及从多元统计角度剖析

    将LDA跟多元统计分析结合起来看,那么LDA中的主题就像词主成分,其把主成分-样本之间的关系说清楚了.多元学的时候聚类分为Q型聚类.R型聚类以及主成分分析.R型聚类.主成分分析针对变量,Q型聚类针对样 ...

  10. R语言︱list用法、批量读取、写出数据时的用法

    列表是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可 以是任意对象,不同元素不必是同一类型.元素本身允许是其它复杂数据类型,比如,列表 的一个元素也允许是列表.例如: > ...