3144: [Hnoi2013]切糕

Description

Input

第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R)。 
100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。

Output

仅包含一个整数,表示在合法基础上最小的总不和谐值。

Sample Input

2 2 2
1
6 1
6 1
2 6
2 6

Sample Output

6

HINT

最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1


  恩。有个同学问我,为什么连几条inf就能保证割边在范围之内?我一下子语塞。过了很久才给了他答复,他一下子欢喜极了。

  另外,需关注题意。我本来连了8个方向,居然还懵了许久。

  对了,这是他的内容:

  这道题显然是一个网络流,我们如果不考虑每次要切的相邻的范围的地方的话,直接从每一竖列的下一层往上一层连边,大概是这么个效果


  对于切糕中的点,我们以虚线的所示方法连边,然后两边以INF的边连S和T,显然跑一边最小割就可以了,然而现在我们还要解决每次切的相邻的范围在d之内…这个对于我这个垃圾来说…简直是难题!…然后我们可以这样连 

  我们从上往下,建INF的边,具体操作是如果可以就向周围的下面的竖直坐标相差为d的点建边,这样一来为什么就可以保证割的边在范围之内呢?我们看上面的图,箭头为正向边的方向,假如图中的A部分被我们割掉了,现在如何才能保证左侧割掉的边一定在左侧的D区域呢?首先我们感性认知一下,现在还存在的路是C-D-B中间进过两条INF的边,还有一条路可以增广,也就是F-D-E这条路,D同时在这两条路里,如果只割一次,那么只能割D

  下一步我们看来思考为什么在两条路中各割一条会比在D中割一条不优…可能是我太智障了,我思考这个图思考了好久233,其实道理很简单啊,观察这张图,如果我们割掉三条长度为1的边,我们能把图增广完嘛?明显不是最小割嘛,割都没割,这里还有一条路嘛

  也就是说,你割外面的边而不割蓝色部分的边,你割都没割到要点,反而多花费了,并且还是有路(并且改路的最大流没有减少)可以通过去,也就是说图上还有一条经过蓝色边的路径可以被割,并且在你割不在蓝色路径上的边之后并没有对这条还可以增广的路造成影响 

  这道题由朱爷分享,代码如下:

 1 /**************************************************************
 2     Problem: 3144
 3     User: Doggu
 4     Language: C++
 5     Result: Accepted
 6     Time:1236 ms
 7     Memory:17652 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13
14 template<class T>inline void readin(T &res) {
15     static char ch;T flag=1;
16     while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
17     res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;res*=flag;
18 }
19
20 const int N = 100100;
21 const int M = 1000010;
22 const int inf = 0x3f3f3f3f;
23 const int dx[] = {-1,1,0,0};
24 const int dy[] = {0,0,-1,1};
25 struct Edge {int v, upre, cap, flow;}g[M];
26 int head[N], ne=-1;
27 inline void adde(int u,int v,int cap) {
28     g[++ne]=(Edge){v,head[u],cap,0};head[u]=ne;
29     g[++ne]=(Edge){u,head[v],0,0};head[v]=ne;
30 }
31
32 #include <queue>
33 std::queue<int> q;
34 int n, m, H, dlt, x, s, t, d[N], cur[N];
35 bool BFS() {
36     memset(d,0,sizeof(d));
37     while(!q.empty()) q.pop();
38     q.push(s);d[s]=1;
39     while(!q.empty()) {
40         int u=q.front();q.pop();
41         for( int i = head[u]; i!=-1; i = g[i].upre ) {
42             int v=g[i].v;
43             if(g[i].cap>g[i].flow&&!d[v]) {q.push(v);d[v]=d[u]+1;}
44         }
45     }
46     return d[t]!=0;
47 }
48 int DFS(int u,int a) {
49     if(u==t||a==0) return a;
50     int flow=0, f;
51     for( int &i = cur[u]; i!=-1; i = g[i].upre ) {
52         int v=g[i].v;
53         if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
54             flow+=f;a-=f;
55             g[i].flow+=f;g[i^1].flow-=f;
56             if(a==0) break;
57         }
58     }
59     if(flow==0) d[u]=0;
60     return flow;
61 }
62 int maxflow() {
63     int flow=0;
64     while(BFS()) {
65         memcpy(cur,head,sizeof(head));
66         flow+=DFS(s,inf);
67     }
68     printf("%d\n",flow);
69 }
70 inline int pos(int i,int j,int h) {return (h-1)*n*m+(i-1)*m+j;}
71 int main() {
72     memset(head,-1,sizeof(head));
73     readin(n);readin(m);readin(H);readin(dlt);s=0;t=66000;
74     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) adde(s,pos(i,j,1),inf), adde(pos(i,j,H+1),t,inf);
75     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) for( int h = 1; h <= H+1; h++ ) if(h+dlt<=H+1)
76         for( int k = 0; k < 4; k++ ) if(1<=i+dx[k]&&i+dx[k]<=n&&1<=j+dy[k]&&j+dy[k]<=m) adde(pos(i+dx[k],j+dy[k],h+dlt),pos(i,j,h),inf);
77     for( int h = 1; h <= H; h++ ) for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) readin(x),adde(pos(i,j,h),pos(i,j,h+1),x);
78     maxflow();
79     return 0;
80 }
81 

dinic最小割建图(1236 ms 17652 kb)

  对了,其中最后一层可以压缩。

 1 /**************************************************************
 2     Problem: 3144
 3     User: Doggu
 4     Language: C++
 5     Result: Accepted
 6     Time:1112 ms
 7     Memory:17652 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13
14 template<class T>inline void readin(T &res) {
15     static char ch;T flag=1;
16     while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
17     res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;res*=flag;
18 }
19
20 const int N = 100100;
21 const int M = 1000010;
22 const int inf = 0x3f3f3f3f;
23 const int dx[] = {-1,1,0,0};
24 const int dy[] = {0,0,-1,1};
25 struct Edge {int v, upre, cap, flow;}g[M];
26 int head[N], ne=-1;
27 inline void adde(int u,int v,int cap) {
28     g[++ne]=(Edge){v,head[u],cap,0};head[u]=ne;
29     g[++ne]=(Edge){u,head[v],0,0};head[v]=ne;
30 }
31
32 #include <queue>
33 std::queue<int> q;
34 int n, m, H, dlt, x, s, t, d[N], cur[N];
35 bool BFS() {
36     memset(d,0,sizeof(d));
37     while(!q.empty()) q.pop();
38     q.push(s);d[s]=1;
39     while(!q.empty()) {
40         int u=q.front();q.pop();
41         for( int i = head[u]; i!=-1; i = g[i].upre ) {
42             int v=g[i].v;
43             if(g[i].cap>g[i].flow&&!d[v]) {q.push(v);d[v]=d[u]+1;}
44         }
45     }
46     return d[t]!=0;
47 }
48 int DFS(int u,int a) {
49     if(u==t||a==0) return a;
50     int flow=0, f;
51     for( int &i = cur[u]; i!=-1; i = g[i].upre ) {
52         int v=g[i].v;
53         if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
54             flow+=f;a-=f;
55             g[i].flow+=f;g[i^1].flow-=f;
56             if(a==0) break;
57         }
58     }
59     if(flow==0) d[u]=0;
60     return flow;
61 }
62 int maxflow() {
63     int flow=0;
64     while(BFS()) {
65         memcpy(cur,head,sizeof(head));
66         flow+=DFS(s,inf);
67     }
68     printf("%d\n",flow);
69 }
70 inline int pos(int i,int j,int h) {if(h==H+1) return t;return (h-1)*n*m+(i-1)*m+j;}
71 int main() {
72     memset(head,-1,sizeof(head));
73     readin(n);readin(m);readin(H);readin(dlt);s=0;t=66000;
74     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) adde(s,pos(i,j,1),inf);
75     for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) for( int h = 1; h <= H+1; h++ ) if(h+dlt<=H+1)
76         for( int k = 0; k < 4; k++ ) if(1<=i+dx[k]&&i+dx[k]<=n&&1<=j+dy[k]&&j+dy[k]<=m) adde(pos(i+dx[k],j+dy[k],h+dlt),pos(i,j,h),inf);
77     for( int h = 1; h <= H; h++ ) for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) readin(x),adde(pos(i,j,h),pos(i,j,h+1),x);
78     maxflow();
79     return 0;
80 }
81 

dinic最小割建图(1112 ms 17652 kb)

转载于:https://www.cnblogs.com/Doggu/p/BZOJ3144.html

BZOJ 3144 [Hnoi2013]切糕相关推荐

  1. BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)

    题面:洛谷传送门 BZOJ传送门 最大流神题 把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边 源点$S$向第$1$层的点连边,第$R+1$ ...

  2. bzoj 3144: [Hnoi2013]切糕

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

  3. BZOJ.3144.[HNOI2013]切糕(最小割)

    题目链接 没有\(D\)的限制怎么做?"最小"我们可以想到最小割,把同一纵轴上的点串起来,分别连到S,T,最小割就是答案.(在这把点权放到前一条边上) 有限制,即如果要割点\(i\ ...

  4. 3144: [Hnoi2013]切糕

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

  5. ●BOZJ 3144 [Hnoi2013]切糕

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3144 题解: "这是一个经典的最小割模型" ---引用自别人的博客 .. ...

  6. bzoj-3144 [Hnoi2013]切糕

    3144 [Hnoi2013]切糕 题目链接 题目大意 给出一个立方体(长宽高分别P,Q,R),按三维坐标每个点记作(x,y,z),点权为V(x,y,z),对于x,y位置从上到下有z层,但只能选择一层 ...

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

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

  8. bzoj 3144(最小割)

    传送门 最小割,主要考查建边的思路.本蒟蒻也是看了好几位大佬的博客才看懂.比如: 参考1 参考2 (x,y,z)连接(x,y,z+1)容量为f(x,y,z) (x,y,z)连接(x',y',z-d)容 ...

  9. 切糕(bzoj 3144)

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

最新文章

  1. MarkDown编辑器基础使用教程
  2. 【划分树+二分】HDU 4417 Super Mario
  3. 技术分享:NodeJS中的Events(事件触发器)讲解
  4. struts2自动接收表单数据
  5. Github Actions:再次改变软件开发
  6. iptables nat实验_【零基础学云计算】LVS负载均衡群集之NAT模式搭建 (实践篇)...
  7. 保留小数点后两位小数
  8. windows server 2008 R2 服务器关机总结
  9. windows7计算机管理,windows7计算机管理
  10. Ionic常见问题--插件无法下载:npm ERR打包sha1错误
  11. 【转】ASP.NET使用ECharts展示后台数据
  12. 人人商城小程序 java版_人人商城小程序用户授权问题
  13. 语法分析器-LL(1)语法分析
  14. FatMouse believes that the fatter a mouse is, the faster it runs.
  15. cloudcompare:怎么换背景颜色
  16. ubuntu16.04耳机没有声音解决办法
  17. ML笔记:预训练(pre-training/trained)与微调(fine tuning)
  18. PHP中冒号加引号,冒号的五种用法 冒号引号的三种用法
  19. 第二次作业:微信实例分析
  20. 前淘宝技术专家谈12306:这个网站很神奇

热门文章

  1. javascript对象包含哪些要素_重学JavaScript 对象
  2. kafka副本数据同步策略
  3. com.alibaba.excel.exception.ExcelAnalysisException: java.lang.NoClassDefFoundError: org/apache/poi/p
  4. 信息系统管理19年真题选择题
  5. FileZilla搭建FTP服务器图解教程
  6. 操作系统:分享10个经常用的cmd命令
  7. 常用的几个JavaScript调试技巧
  8. python刷题用leet_GitHub - Yolymaker/leetcode-python: 利用python分类刷leetcode题目
  9. linux ll命令无效
  10. 你提交代码前没有校验?巧用gitHooks解决