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 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn=45,maxm=100005,inf=0x3f3f3f3f;
 7 int map[maxn][maxn][maxn],ord[maxn][maxn][maxn],p,q,r,cnt,S,T,d,fx[4]={0,0,1,-1},fy[4]={1,-1,0,0};
 8 struct node
 9 {
10     int from,to,flow,next;
11 }edge[maxm<<3];
12 int head[maxm],tot;
13 void addedge(int u,int v,int w)
14 {
15     edge[tot]=(node){u,v,w,head[u]};head[u]=tot++;
16     edge[tot]=(node){v,u,0,head[v]};head[v]=tot++;
17 }
18 #include<queue>
19 int dis[maxm],g[maxm];
20 bool bfs()
21 {
22     memset(dis,0,sizeof(dis));
23     dis[S]=1;
24     queue<int>q;q.push(S);
25     while(!q.empty())
26     {
27         int u=q.front();q.pop();
28         for(int i=head[u];i!=-1;i=edge[i].next)
29         {
30             int v=edge[i].to;
31             if(edge[i].flow>0&&!dis[v])
32             {
33                 dis[v]=dis[u]+1;
34                 q.push(v);
35             }
36         }
37     }
38     return dis[T];
39 }
40 int dfs(int pos,int flow)
41 {
42     if(pos==T||!flow)return flow;
43     int f=0;
44     for(int &i=g[pos];i!=-1;i=edge[i].next)
45     {
46         int v=edge[i].to;
47         if(dis[v]==dis[pos]+1&&edge[i].flow>0)
48         {
49             int t=dfs(v,min(flow,edge[i].flow));
50             if(t>0)
51             {
52                 flow-=t;f+=t;
53                 edge[i].flow-=t;
54                 edge[i^1].flow+=t;
55                 if(!flow)break;
56             }
57         }
58     }
59     return f;
60 }
61 int haha()
62 {
63     freopen("nutcake.in","r",stdin);
64     freopen("nutcake.out","w",stdout);
65     memset(head,-1,sizeof(head));
66     scanf("%d%d%d",&p,&q,&r);
67     scanf("%d",&d);
68     for(int i=1;i<=p;i++)
69         for(int j=1;j<=q;j++)
70             for(int k=1;k<=r;k++)ord[i][j][k]=++cnt;
71     S=0,T=cnt+1;
72     for(int k=1;k<=r;k++)
73         for(int i=1;i<=p;i++)
74             for(int j=1;j<=q;j++)
75             {
76                 int z;scanf("%d",&z);
77                 if(k==1)addedge(S,ord[i][j][k],z),addedge(ord[i][j][r],T,inf);
78                 else addedge(ord[i][j][k-1],ord[i][j][k],z);
79                 if(k>d)
80                     for(int l=0;l<4;l++)
81                     {
82                         int x=i+fx[l],y=j+fy[l];
83                         if(ord[x][y][k-d])addedge(ord[i][j][k],ord[x][y][k-d],inf);
84                     }
85             }
86     int ans=0;
87     while(bfs())
88     {
89         for(int i=S;i<=T;i++)g[i]=head[i];
90         ans+=dfs(S,T);
91     }
92     printf("%d\n",ans);
93 }
94 int sb=haha();
95 int main(){;}

cogs2398

时间: 2024-10-06 00:12:55

cogs2398 切糕 最小割的相关文章

【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≤

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

【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

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,且给出的所有的不和谐值不超

BZOJ_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 O

[BZOJ 3144] [Hnoi2013] 切糕 【最小割】

题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的差的绝对值不能超过 D . 求一个合法的最小总代价. 这道题是一个最小割模型,直接说建图吧. 建图:每个点 (x, y) 拆成 R 个点,(x, y, z) 代表 (x, y) 填 z. 然后从 S 向 (*, *, 1) 连 INF ,从 (*, *, R) 向 T 连 INF . 然后对于 (i