BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
最大流神题
把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边
源点$S$向第$1$层的点连边,第$R+1$层的点向$T$连边,流量均为$inf$
跑最大流,最大流的流量就是答案
因为每条纵轴都取了最小的$v$,被割掉的边就是最小的$v$所在的边
然而题目里还有限制,相邻两个纵轴取值的位置相差的距离不能超过$D$
如何处理这个限制呢?
每个点$(i,j,k)$向$(x,y,k-D)$连流量为$inf$的边,$(x,y)$是$(i,j)$相邻的纵轴
假设纵轴$(i,j)$的割点是$(i,j,k)$
如果$(x,y)$的割点在$(x,y,k-D)$下面,一定会有一条流量从纵轴$(i,j)$流到$(x,y)$里,然后向上流到汇点$T$
巧妙地解决了距离的限制问题
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 67010
#define M1 400010
#define L1 45
using namespace std;
const int inf=0x3f3f3f3f; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
struct Edge{
int to[M1<<],nxt[M1<<],flow[M1<<],head[N1],cte;
void ae(int u,int v,int f)
{
cte++; to[cte]=v; nxt[cte]=head[u];
head[u]=cte; flow[cte]=f;
}
}e; int dep[N1],que[M1],cur[N1],n,m,h,D,hd,tl,S,T;
int bfs()
{
int x,j,v;
memset(dep,-,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));
hd=,tl=; que[++tl]=S; dep[S]=;
while(hd<=tl)
{
x=que[hd++];
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j];
if( dep[v]==- && e.flow[j]> )
{
dep[v]=dep[x]+;
que[++tl]=v;
}
}
}
return dep[T]!=-;
}
int dfs(int x,int limit)
{
int j,v,flow,ans=;
if(!limit||x==T) return limit;
for(j=cur[x];j;j=e.nxt[j])
{
v=e.to[j]; cur[x]=j;
if( dep[v]==dep[x]+ && (flow=dfs(v,min(limit,e.flow[j]))) )
{
e.flow[j]-=flow; limit-=flow;
e.flow[j^]+=flow; ans+=flow;
if(!limit) break;
}
}
return ans;
}
int Dinic()
{
int mxflow=,j,v,ans=;
while(bfs())
mxflow+=dfs(S,inf);
return mxflow;
} int xx[]={-,,,},yy[]={,,,-};
int v[L1][L1][L1],id[L1][L1][L1];
inline int check(int x,int y){return (x<||y<||x>n||y>m)?:;} int main()
{
scanf("%d%d%d%d",&n,&m,&h,&D);
int i,j,k,x,y,w,p; e.cte=; S=; T=n*m*(h+)+;
for(k=;k<=h+;k++) for(i=;i<=n;i++) for(j=;j<=m;j++) id[k][i][j]=(k-)*n*m+(i-)*m+j;
for(k=;k<=h;k++) for(i=;i<=n;i++) for(j=;j<=m;j++)
{
w=v[k][i][j]=gint(), x=id[k][i][j];
e.ae(x,x+n*m,w), e.ae(x+n*m,x,);
if(k<=D) continue;
//x+=n*m;
for(p=;p<;p++)
{
if(!check(i+xx[p],j+yy[p])) continue;
y=id[k-D][i+xx[p]][j+yy[p]];
e.ae(x,y,inf); e.ae(y,x,);
}
}
for(i=;i<=n;i++) for(j=;j<=m;j++) e.ae(S,id[][i][j],inf), e.ae(id[][i][j],S,);
for(i=;i<=n;i++) for(j=;j<=m;j++) e.ae(id[h+][i][j],T,inf), e.ae(T,id[h+][i][j],);
printf("%d\n",Dinic());
return ;
}
BZOJ 3144 [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 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的 ...
- 洛谷 P3227 BZOJ 3144 [HNOI2013]切糕
题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案 ...
- [NOI2008][bzoj1061] 志愿者招募 [费用流+巧妙的建图]
题面 传送门 思路 引入:网络流? 看到这道题,第一想法是用一个dp来完成决策 但是,显然这道题的数据并不允许我们进行dp,尤其是有10000种志愿者的情况下 那么我们就要想别的办法来解决: 贪心?这 ...
- 【刷题】BZOJ 3144 [Hnoi2013]切糕
Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x, ...
- bzoj 3144 [Hnoi2013]切糕——最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3144 一根纵轴上切一个点,可以把一根纵轴上的点连成一串来体现.自己的写法是每个点连向前一个点 ...
- BZOJ 3144 [Hnoi2013]切糕 ——网络流
[题目分析] 网络流好题! 从割的方面来考虑问题往往会得到简化. 当割掉i,j,k时,必定附近的要割在k-D到k+D上. 所以只需要建两条inf的边来强制,如果割不掉强制范围内的时候,原来的边一定会换 ...
- bzoj 3144 [Hnoi2013]切糕【最小割+dinic】
都说了是'切'糕所以是最小割咯 建图: 每个点向下一层连容量为这个点的val的边,S向第一层连容量为inf的边,最后一层向T连容量为自身val的边,即割断这条边相当于\( f(i,j) \)选择了当前 ...
随机推荐
- 【iOS开发系列】九宫格布局
/** * 这个尽管非常easy,算是一个小技巧,可是碰到了就记录下来吧.积跬步,致千里嘛. */ - (void)scratchableLatex { for (int i=0; i<9; i ...
- 一、Redis 基础命令---总括
1.redis命令不区分大写和小写.可是KEY区分大写和小写. 2.redis-cli -h 127.0.0.1 -p 6379 依据IP/PORT链接服务端 3.redis-server --por ...
- CentOS 7通过yum安装fcitx五笔输入法
CentOS 7通过yum安装fcitx五笔输入法 下面通过了亲測: 1.设置源 Posted in Linux at 三月 5th, 2015 / No Comments ? 增加EPEL源 EPE ...
- 黑马day01xml 解析方式与原理分析
dom解析方式和sax解析
- JPA相关注解
JPA注解 一.基本注解 1.表相关 @Entity 仅仅要加了这个注解就具备了表和实体的映射关系,表名就是实体名 @Table(name="表名") 一般和实体 ...
- Linux系统的命令源码的获取方法
我们知道,Linux是开源的,它自带的功能强大的命令也是开源的,也就是说.我们能够获得这些命令的源码并研究它.那到底怎样获得系统的命令的源码呢? 命令的源码是一个软件包为单元的,放在一个软件包的源码中 ...
- h5-8 canvas
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 网络:万维网(WWW)
ylbtech-网络:万维网(WWW) www (万维网缩写)同义词 万维网一般指www(万维网缩写)WWW是环球信息网的缩写,(亦作“Web”.“WWW”.“'W3'”,英文全称为“World Wi ...
- 【BZOJ2806】【CTSC2012】Cheat 广义后缀自动机+二分+Dp
题目 题目在这里 思路&做法 我们先对标准作文库建广义后缀自动机. 然后对于每一篇阿米巴的作文, 我们首先把放到广义后缀自动机跑一遍, 对于每一个位置, 记录公共子串的长度\((\)即代码和下 ...
- JAVA 中for-each循环使用方法
for each循环还是第一次见,“java SE 5.0增加了一种功能很强的循环结构,可以用来一次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心”. 这种增强的for eac ...