BZOJ3144 切糕

http://www.lydsy.com/JudgeOnline/problem.php?id=3144

思路:如果没有D的限制,那一个竖轴都是一个最小割,每个点向更高的点引一条流量为自己权值的边,那考虑D的情况,就表明在割i高度这条边的时候,不能割它相邻的i-d以下的任何边,因此,我们引一条边从i高度到相邻的i-d高度,流量为inf,这样就能维护D这个条件了

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 int d[5][5];
 8 int sz,id[50][50][50],S,T,nodes,P,Q,R,D;
 9 int tot,go[2000005],next[2000005],first[2000005],flow[2000005];
10 int op[2000005],dis[2000005],cnt[2000005],v[50][50][50];
11 int read(){
12     int t=0,f=1;char ch=getchar();
13     while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-1;ch=getchar();}
14     while (‘0‘<=ch&&ch<=‘9‘){t=t*10+ch-‘0‘;ch=getchar();}
15     return t*f;
16 }
17 void insert(int x,int y,int z){
18     tot++;
19     go[tot]=y;
20     next[tot]=first[x];
21     first[x]=tot;
22     flow[tot]=z;
23 }
24 void add(int x,int y,int z){
25     insert(x,y,z);op[tot]=tot+1;
26     insert(y,x,0);op[tot]=tot-1;
27 }
28 int dfs(int x,int f){
29     if (x==T) return f;
30     int mn=nodes,sum=0;
31     for (int i=first[x];i;i=next[i]){
32         int pur=go[i];
33         if (flow[i]&&dis[pur]+1==dis[x]){
34             int F=std::min(f-sum,flow[i]);
35             int save=dfs(pur,F);
36             flow[i]-=save;
37             flow[op[i]]+=save;
38             sum+=save;
39             if (sum==f||dis[S]>=nodes) return sum;
40         }
41         if (flow[i]) mn=std::min(mn,dis[pur]);
42     }
43     if (sum==0){
44         cnt[dis[x]]--;
45         if (cnt[dis[x]]==0) dis[S]=nodes;
46         else {
47             dis[x]=mn+1;
48             cnt[dis[x]]++;
49         }
50     }
51     return sum;
52 }
53 int main(){
54     P=read();Q=read();R=read();
55     D=read();
56     for (int i=1;i<=R+1;i++)
57      for (int j=1;j<=P;j++)
58       for (int k=1;k<=Q;k++)
59        id[i][j][k]=++sz;
60     S=0;T=sz+1;nodes=T+1;
61     for (int i=1;i<=R;i++)
62      for (int j=1;j<=P;j++)
63       for (int k=1;k<=Q;k++)
64        v[i][j][k]=read();
65     for (int j=1;j<=P;j++)
66      for (int k=1;k<=Q;k++)
67       add(S,id[1][j][k],inf);
68     for (int j=1;j<=P;j++)
69      for (int k=1;k<=Q;k++)
70       add(id[R+1][j][k],T,inf);
71     for (int i=1;i<=R;i++)
72      for (int j=1;j<=P;j++)
73       for (int k=1;k<=Q;k++)
74        add(id[i][j][k],id[i+1][j][k],v[i][j][k]);
75     d[1][1]=d[2][2]=1;d[3][1]=d[4][2]=-1;
76     for (int i=1;i<=R;i++)
77      if (i>D)
78      for (int j=1;j<=P;j++)
79       for (int k=1;k<=Q;k++)
80         for (int l=1;l<=4;l++){
81             int dx=j+d[l][1],dy=k+d[l][2];
82             if (dx<1||dx>P||dy<1||dy>Q) continue;
83             add(id[i][j][k],id[i-D][dx][dy],inf);
84         }
85     int ans=0;
86     while (dis[S]<nodes) ans+=dfs(S,inf);
87     printf("%d\n",ans);
88     return 0;
89 }
时间: 2024-10-23 04:03:38

BZOJ3144 切糕的相关文章

bzoj-3144 切糕

题意: 给出一个R*P*Q的三维点阵,求一个函数f(x,y)  (1<=x<=P,1<=y<=Q): 使∑v[f(x,y)][x][y]最小,且相邻两个f值之差不超过D: R,P,Q<=40,v<=1000: 题解: 看起来就好神的题,然而就算告诉我是网络流我也不信能跑64000个点: 不过事实上= =,数据中最大是30 30 30的..所以结果大家跑的都很快: 这道题的建图就是首先限制在一行只能选择一个,那么从上向下连出一条链,每个弧的流量都是对应点的权值: 如果不考

bzoj3144 [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 样例1: 2 2 2 1 6 1 6 1 2 6 2 6 样例

【bzoj3144】[Hnoi2013]切糕 网络流最小割

题目描述 输入 第一行是三个正整数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. 输出 仅包含一个整数,表示在合法基础上最小的总不和谐值. 样例输入 2 2 2 1 6 1 6 1 2 6 2 6 样例输出 6 题目大意 给定一个p行q列的矩阵,每个位置可以

【BZOJ-3144】切糕 最小割-最大流

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1261  Solved: 700[Submit][Status][Discuss] 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

bzoj3144【HNOI2013】切糕

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1188  Solved: 658 [Submit][Status][Discuss] 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

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

http://www.lydsy.com/JudgeOnline/problem.php?id=3144 如果D=2 ,两个点,高度为4,建图如下 #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 64005 #define M 323205 const i

【bzoj3144】[Hnoi2013]切糕 最小割

[Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2228  Solved: 1220[Submit][Status][Discuss] 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

[HNOI2013]切糕

题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案. 出于简便考虑,我们将切糕视作一个长 P.宽 Q.高 R 的长方体点阵.我们将位于第 z层中第 x 行.第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z).一个合法的切面满足以下两个条件: 与每个纵轴(一共有 P*Q 个纵轴)有且

洛谷 P3227 BZOJ 3144 [HNOI2013]切糕

题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案. 出于简便考虑,我们将切糕视作一个长 P.宽 Q.高 R 的长方体点阵.我们将位于第 z层中第 x 行.第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z).一个合法的切面满足以下两个条件: 与每个纵轴(一共有 P*Q 个纵轴)有且