[BZOJ 3144] 切糕
Link:
Solution:
发现要把点集分成不连通的两部分,最小割的模型还是很明显的
首先我们将原图转化为$R+1$层,从而将点权化为边权
关键还是在于建图是怎么保证$|h_i-h_j|<=D$这个条件
要保证$|h_i-h_j|<=D$这个条件也就意味着选了$i$就不能选$j$,但仍然要保证$i->j$的连通性
于是我们由$i+D$向$i$连一条边权为$INF$的边,
这样如果割掉$i,j(j>i+D)$但不选择它们之间的边,就不会影响ST的连通性
只能再割掉$INF$边或其他边,这样两边同时选择明显不会计入答案
同时$i,j(j<=i+D)$就不会出现这样的问题,于是通过设置$INF$边就解决了这个问题
如上图,如果仅割掉右侧绿边和左侧红边,中间黑色的$INF$边仍会保持ST的连通性
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=**;
const int INF=;
int P,Q,R,D,S,T,id[][][],iter[MAXN],level[MAXN],cnt=,x;
int dx[]={,,,-},dy[]={,-,,};
struct edge
{
int to,cap,rev;
};
vector<edge> G[MAXN]; void add_edge(int from,int to,int cap)
{
G[from].push_back(edge{to,cap,G[to].size()});
G[to].push_back(edge{from,,G[from].size()-});
} bool bfs()
{
memset(level,-,sizeof(level));
queue<int> que;que.push(S);level[S]=;
while(!que.empty())
{
int v=que.front();que.pop();
for(int i=;i<G[v].size();i++)
{
edge &e=G[v][i];
if(e.cap && level[e.to]==-)
level[e.to]=level[v]+,que.push(e.to);
}
}
return (level[T]>);
} int dfs(int v,int f)
{
if(v==T) return f;
for(int &i=iter[v];i<G[v].size();i++)
{
edge &e=G[v][i];
if(level[e.to]==level[v]+ && e.cap)
{
int d=dfs(e.to,min(f,e.cap));
if(d)
{
e.cap-=d;G[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
} int Dinic()
{
int ret=;
while(bfs())
{
memset(iter,,sizeof(iter));
int f;
while((f=dfs(S,INF))>) ret+=f;
}
return ret;
} int main()
{
scanf("%d%d%d%d",&P,&Q,&R,&D);
S=;
for(int i=;i<=R+;i++) for(int j=;j<=P;j++) for(int k=;k<=Q;k++) //预处理出编号
id[i][j][k]=++cnt;
T=++cnt; for(int i=;i<=R;i++) for(int j=;j<=P;j++) for(int k=;k<=Q;k++)
scanf("%d",&x),add_edge(id[i][j][k],id[i+][j][k],x); for(int i=;i<=P;i++) for(int j=;j<=Q;j++)
add_edge(S,id[][i][j],INF),add_edge(id[R+][i][j],T,INF); for(int i=D+;i<=R+;i++) for(int j=;j<=P;j++) for(int k=;k<=Q;k++)
for(int dir=;dir<;dir++)
{
int fx=j+dx[dir],fy=k+dy[dir];
if(!id[i-D][fx][fy]) continue;
add_edge(id[i][j][k],id[i-D][fx][fy],INF);
} printf("%d",Dinic());
return ;
}
Review:
1、认真审题,不要主观带入
这题一开始想成了切割线必须在同一个平面,还是不能读题时自己想当然啊
2、最小割模型的新套路
最小割的重点便在于割边计入答案
如果不想让两条边同时计入答案,可以在它们之间加入一条$INF$边,
保证同时选择两边时不会影响原图ST的连通性且$INF$边不会影响结果
使得同时选择两边时一定不符合最小的条件,从而不会计入答案
3、点权变边权
可以通过点变边,边变点的方式完成这样的转换
[BZOJ 3144] 切糕的更多相关文章
- BZOJ 3144 切糕(最小割)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3144 题意: 思路:我们假设没有那个D的限制.这样就简 单了.贪心的话,我们只要在每一个 ...
- bzoj 3144 切糕 —— 最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3144 每个点拆成 R 个,连成一条链,边上是权值,割掉代表选这一层: 然后每个点的第 t 层 ...
- BZOJ 3144 切糕 最小割
题意: 一个矩阵,每个格子分配一个数,不同的数字,代价不同,要求相邻格子数字差小等于d 求最小代价. 分析: 我猜肯定有人看题目就想到最小割了,然后一看题面理科否决了自己的这个想法…… 没错,就是最小 ...
- [BZOJ 3144][HNOI 2013] 切糕
题目大意 切糕是 (p times q times r) 的长方体,每个点有一个违和感 (v_{x, y, z}).先要水平切开切糕(即对于每个纵轴,切面与其有且只有一个交点),要求水平上相邻两点的切 ...
- [BZOJ 3144] [Hnoi2013] 切糕 【最小割】
题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的 ...
- 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】 3144: [Hnoi2013]切糕 (最小割模型)
3144: [Hnoi2013]切糕 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1764 Solved: 965 Description Inp ...
- BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
题面:洛谷传送门 BZOJ传送门 最大流神题 把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边 源点$S$向第$1$层的点连边,第$R+1$ ...
随机推荐
- [ST表/贪心] NOI2010 超级钢琴
[NOI2010]超级钢琴 题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i ...
- Ubuntu修改grub启动顺序和启动时间
sudo gedit /boot/grub/grub.cfg,输入密码,在弹出的文件中找到set default = "0",想要改为第N项默认就把0改成N-1 看到启动界面是第几 ...
- JS知识总结
1.javascript继承机制 原型继承,访问对象属性时,如果对象内部有就返回,找不到就会从对象原型指向的对象原型中查找,一层一层的查找,直到最顶层的对象原型还找不到,就返回undefined. 2 ...
- 动态规划:划分DP
划分型动态规划之数的划分 先贴上2014年10月31日的那份代码,甚至怀念当时在机房YY这道题的场面 高中最快乐的时候.. #include<iostream> using namespa ...
- python中orm框架学习
安装sqlalchemy pip3 install sqlalchemy 创建表结构: from sqlalchemy import Column,String,create_engine from ...
- DB 基本性能指标
DB: •500K I/O limit with kill(5M I/O limit for DWS) •10,000 return row limit with kill •30 seconds p ...
- magento目录了解
对magento目录的了解:
- bzoj 1293 贪心
首先我们可以将这道题看成一个数轴,数轴其中的某些点存在一些颜色,我们要选取最短的一段,使这段存 在所有颜色,那么我们使用指针i,j表示在j-i位置中包含的颜色,那么初值是0,0,我们先i++,同时添加 ...
- 线程局部存储 TLS
C/C++运行库提供了TLS(线程局部存储),在多线程还未产生时,可以将数据与正在执行的线程关联.strtok()函数就是一个很好的例子.与它一起的还有strtok_s(),_tcstok_s()等等 ...
- 编写类du命令Python脚本
#!/usr/bin/env python #_*_ coding:utf-8 _*_ #计算整个目录的大小,脚本接受-H参数,来加上适当的单位 #功能像du看齐 import os,sys from ...