【HNOI2013】切糕

Sample Input

2 2 2

1

6 1

6 1

2 6

2 6

Sample Output

6

\(P,Q,R≤40,0≤D≤R\)

参考:https://blog.csdn.net/zarxdy34/article/details/45272055

经典的有距离限制的网络流模型。

首先我们不考虑高度限制。我们直接将图建\(r+1\)层,就是每个格子\((x,y)\)拆成\(r+1\)个点。将它们串成一串,第\(i\)层的向\(i+1\)层连边,第\(i\)条边的容量就是\(v_{x,y,i}\)。然后源点向第\(1\)层的连边,第\(r+1\)层的向汇点连边。最小割就是答案。

考虑怎么将距离限制表示出来。对于所有的格子\((x,y)\),假设是第\(k\)层的图,那么我们向第\(k-d\)层的\((x,y)\)周围的点连\(\infty\)的边。

考虑这么做的合法性。两个相邻的格子\((x,y),(x',y')\),如果我们选了\(v_{x,y,k}\),也就是割断了第\(k\)层\((x,y)\)连出去的边,那么\((x',y')\)选的高度\(k'\)要\(\geq k-D\)。如果\((x',y')\)割断了\(k-D\)以下的边,那么\((x,y)\)和\((x',y')\)之间\(\infty\)的边就会实源点和汇点连通。

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define N 45
  4. using namespace std;
  5. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  6. const int V=N*N*N;
  7. int n,m,r;
  8. int D;
  9. int v[N][N][N];
  10. int id[N][N];
  11. struct road {
  12. int to,next;
  13. int flow;
  14. }s[V<<3];
  15. int h[V],cnt=1;
  16. void add(int i,int j,int f) {
  17. s[++cnt]=(road) {j,h[i],f};h[i]=cnt;
  18. s[++cnt]=(road) {i,h[j],0};h[j]=cnt;
  19. }
  20. int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
  21. int S,T;
  22. int dis[V];
  23. queue<int>q;
  24. bool bfs() {
  25. memset(dis,0x3f,sizeof(dis));
  26. q.push(S);
  27. dis[S]=0;
  28. while(!q.empty()) {
  29. int v=q.front();
  30. q.pop();
  31. for(int i=h[v];i;i=s[i].next) {
  32. int to=s[i].to;
  33. if(s[i].flow&&dis[to]>dis[v]+1) {
  34. dis[to]=dis[v]+1;
  35. q.push(to);
  36. }
  37. }
  38. }
  39. return dis[T]<1e9;
  40. }
  41. int dfs(int v,int maxf) {
  42. if(v==T) return maxf;
  43. int ret=0;
  44. for(int i=h[v];i;i=s[i].next) {
  45. int to=s[i].to;
  46. if(s[i].flow&&dis[to]==dis[v]+1) {
  47. int dlt=dfs(to,min(maxf,s[i].flow));
  48. s[i].flow-=dlt;
  49. s[i^1].flow+=dlt;
  50. ret+=dlt;
  51. maxf-=dlt;
  52. if(!maxf) return ret;
  53. }
  54. }
  55. return ret;
  56. }
  57. int dinic() {
  58. int ans=0;
  59. while(bfs()) {
  60. while(1) {
  61. int tem=dfs(S,1e9);
  62. if(!tem) break;
  63. ans+=tem;
  64. }
  65. }
  66. return ans;
  67. }
  68. int main() {
  69. n=Get(),m=Get(),r=Get();
  70. D=Get();
  71. for(int k=1;k<=r;k++)
  72. for(int i=1;i<=n;i++)
  73. for(int j=1;j<=m;j++)
  74. v[i][j][k]=Get();
  75. int tot=n*m;
  76. for(int i=1;i<=n;i++)
  77. for(int j=1;j<=m;j++)
  78. id[i][j]=(i-1)*m+j;
  79. T=(r+1)*tot+1;
  80. for(int i=1;i<=n;i++)
  81. for(int j=1;j<=m;j++)
  82. add(S,id[i][j],1e9),add(id[i][j]+r*tot,T,1e9);
  83. for(int k=1;k<=r;k++) {
  84. for(int i=1;i<=n;i++) {
  85. for(int j=1;j<=m;j++) {
  86. add((k-1)*tot+id[i][j],k*tot+id[i][j],v[i][j][k]);
  87. if(k>D) {
  88. int nxt=k-D;
  89. for(int d=0;d<4;d++) {
  90. int a=i+dx[d],b=j+dy[d];
  91. if(a<1||a>n||b<1||b>m) continue ;
  92. add((k-1)*tot+id[i][j],(nxt-1)*tot+id[a][b],1e9);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. cout<<dinic();
  99. return 0;
  100. }

【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. c# 大批量用户访问数据库报错

    报错信息:There is already an open DataReader associated with this Connection which must be closed first ...

  2. spring_03ApplicationContext三种经常用到的实现

    1.ClassPathXmlApplicationContext从类路径加载 ApplicationContext ac=new ClassPathXmlApplicationContext(&quo ...

  3. Elasticsearch系列(2):安装Elasticsearch(Linux环境)

    系统环境 操作系统:CentOS 6.9 Elasticsearch:6.2.2 Filebeat:6.2.2(收集IIS日志) Kibana:6.2.2 Java:Java 8 注意:elk最好选择 ...

  4. C#设计模式之十九策略模式(Stragety Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第七个模式,该模式是[策略模式],英文名称是:Stragety Pattern.在现实生活中,策略模式的例子也非常常见,例如,在一个公司中,会有各种工作人员 ...

  5. check约束

    -- 删除表 drop table check_test; -- 不为空,不为null的值只能是0,1(不为空,值只能是0,1) create table check_test( default_fl ...

  6. JavaScript字符串转换为数字

    今天在工作中碰到了一个问题,要将字符串转换为数字,否则函数不能正常工作, 特地研究了下,写了2个函数,供大家参考,代码如下: /** * 将字符串转换为数字 * @param {Object} str ...

  7. jquery对象和DOM对象的相互转换详解

    jquery对象和DOM对象的相互转换 在讨论jquery对象和DOM对象的相互转换之前,先约定好定义变量的风格如果获取的是jquery对象,那么在变量前面加上$,例如 var $varible = ...

  8. 通过JS生成由字母与数字组合的随机字符串

    在项目中可能需要随机生成字母数字组成的字符,如生成3-32位长度的字母数字组合的随机字符串(位数不固定)或者生成43位随机字符串(位数固定) 使用Math.random()与toString()方法的 ...

  9. 洛谷P3246 [HNOI2016]序列(离线 差分 树状数组)

    题意 题目链接 Sol 好像搞出了一个和题解不一样的做法(然而我考场上没写出来还是爆零0) 一个很显然的思路是考虑每个最小值的贡献. 预处理出每个数左边第一个比他小的数,右边第一个比他大的数. 那么\ ...

  10. Django引入静态文件

    在HTML文件中引入方式: 简单引入一个bootstrap中的内敛表单,效果图如下: