【bzoj3144】[Hnoi2013]切糕 最小割

[Hnoi2013]切糕

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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,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

Source

题解:

  题意表示看不懂了,语文水平差,没办法。

  切割就是每条竖线上选择一个点来断开,

  如果没有这个限制是什么,就是直接一层中的点向下一层对应的点连边

  那么限制的话就是当前的点割了不能割

  那么就是也可以转换为,割了这条边,与其相距d的边割了无效

  发现一个点向上向下都制约D和每个点都只向下制约是等价的

  所以从该点向下d连一条无穷的边,不能割

当时看这个人才会的

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6
  7 #define rad 100000000
  8 #define inf 1000000000
  9 #define ll long long
 10 #define eps 1e-10
 11 #define pa pair<ll,int>
 12 using namespace std;
 13 ll read()
 14 {
 15     ll x=0,f=1;char ch=getchar();
 16     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 17     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 18     return x*f;
 19 }
 20
 21 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
 22 int P,Q,r,d,T,cnt=1;
 23 int f[45][45][45];
 24 int cur[100005],last[100005],h[100005],q[100005];
 25
 26 struct edge{
 27     int to,next,v;
 28 }e[1000005];
 29 int p(int x,int y,int z)
 30 {
 31     if(z==0)return 0;
 32     return (z-1)*P*Q+(x-1)*Q+y;
 33 }
 34 void insert(int u,int v,int w)
 35 {
 36     e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
 37     e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=0;
 38 }
 39 void build()
 40 {
 41     for(int i=1;i<=P;i++)
 42         for(int j=1;j<=Q;j++)
 43         {
 44             for(int k=1;k<=r;k++)
 45             {
 46                 insert(p(i,j,k-1),p(i,j,k),f[i][j][k]);
 47                 if(k>d)
 48                 for(int dir=0;dir<4;dir++)
 49                 {
 50                     int nx=i+xx[dir],ny=j+yy[dir];
 51                     if(nx<1||ny<1||nx>P||ny>Q)continue;
 52                     insert(p(i,j,k),p(nx,ny,k-d),inf);
 53                 }
 54             }
 55             insert(p(i,j,r),T,inf);
 56         }
 57 }
 58 bool bfs()
 59 {
 60     int head=0,tail=1;
 61     memset(h,-1,sizeof(h));
 62     q[0]=0;h[0]=0;
 63     while(head!=tail)
 64     {
 65         int now=q[head];head++;
 66         for(int i=last[now];i;i=e[i].next)
 67             if(h[e[i].to]==-1&&e[i].v)
 68             {
 69                 h[e[i].to]=h[now]+1;
 70                 q[tail++]=e[i].to;
 71             }
 72     }
 73     return h[T]!=-1;
 74 }
 75 int dfs(int x,int f)
 76 {
 77     if(x==T)return f;
 78     int w,used=0;
 79     for(int i=cur[x];i;i=e[i].next)
 80         if(h[x]+1==h[e[i].to])
 81         {
 82             w=dfs(e[i].to,min(f-used,e[i].v));
 83             used+=w;e[i].v-=w;e[i^1].v+=w;
 84             if(e[i].v)cur[x]=i;
 85             if(used==f)return f;
 86         }
 87     if(!used)h[x]=-1;
 88     return used;
 89 }
 90 int dinic()
 91 {
 92     int tmp=0;
 93     while(bfs())
 94     {
 95         for(int i=0;i<=T;i++)cur[i]=last[i];
 96         tmp+=dfs(0,inf);
 97     }
 98     return tmp;
 99 }
100 int main()
101 {
102     P=read();Q=read();r=read();T=P*Q*r+1;
103     d=read();
104     for(int i=1;i<=r;i++)
105         for(int j=1;j<=P;j++)
106             for(int k=1;k<=Q;k++)
107                 f[j][k][i]=read();
108     build();
109     printf("%d\n",dinic());
110 }

原文地址:https://www.cnblogs.com/fengzhiyuan/p/8277395.html

时间: 2024-12-26 18:13:36

【bzoj3144】[Hnoi2013]切糕 最小割的相关文章

【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

bzoj 3144: [Hnoi2013]切糕 最小割

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

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 样例

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

BZOJ 3144 HNOI 2013 切糕 最小割

题目大意:给出一个三维的点阵,没个点都有可能被切割,代价就是这个点的权值.相邻的切割点的高度差不能超过D,问最小的花费使得上下分开. 思路:很裸的最小割模型,很神的建图. S->第一层的点,f:INF 所有点->它下面的点,f:INF 一个点的入->一个点的出,f:val[i] (i,j,k) - > (i - d,j,k),f:INF 最下面一层的点->T:f:INF 然后跑最小割就是答案. 为什么见:http://www.cnblogs.com/zyfzyf/p/4182

cogs2398 切糕 最小割

链接:http://cogs.pro/cogs/problem/problem.php?pid=2398 题意:找到一个最小割使损失最小. 字面意思,单纯的最小割.对于每一个点$(i,j,k)$,我们将其与它下方的点$(i,j,k-1)$,连一条容量为该点不和谐度的边,如果高度为1,连到源点,高度为n,建出一条到汇点容量无限大的边.对于高度超过限制高度的点,我们由周围下方可行点向它连容量无限大边. 1 #include<iostream> 2 #include<cstdio> 3

bzoj 3144 切糕 —— 最小割

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3144 每个点拆成 R 个,连成一条链,边上是权值,割掉代表选这一层: 然后每个点的第 t 层向四周的点的第 t-d 层连边,就能达到选了第 i 条边,则四周的点必须选 i-d ~ T 范围的边,而对方反过来一连,就限制在 i-d ~ i+d 了: 竟然因为忘记 ct=1 而调了一小时呵呵... 代码如下: #include<cstdio> #include<cstring>

【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]切糕 (最小割模型)

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1764  Solved: 965 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,且给出的所有的不和谐值不超