【bzoj3144】【HNOI2013】【切糕】【最小割】
来源:互联网 发布:大学生分期软件2017 编辑:程序博客网 时间:2024/04/26 08:02
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
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
题解:考虑限制1:我们只需要将(x,y)相同的从上到下依次连起来即可,上面的点向下面的点连下面点权值的边。
考虑限制2:我们必须保证选不合法的点的集合的时候图仍然是联通的。
所以对于每个点,我们只需要从(x,y,z)向(x,y,z+d)连一条inf的边即可。
这样无法统计第一层点的权值,所以我们对于每个(x,y)建一个虚拟节点,从源点向它连inf的边,从它向第一层(x,y)连那个点权值的边即可。
最小割即是答案。
代码:
#include<iostream>#include<cstdio>#include<cstring>#define N 70000#define M 400000#define INF 2100000000using namespace std;int point[N],next[M<<1],cnt(1),p,q,r,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};int cur[N],dis[N],pre[N],gap[N],a[50][50][50],d,T;struct use{int st,en,v;}e[M<<1];bool f;void add(int x,int y,int v){ next[++cnt]=point[x];point[x]=cnt;e[cnt].st=x;e[cnt].en=y;e[cnt].v=v; next[++cnt]=point[y];point[y]=cnt;e[cnt].st=y;e[cnt].en=x;e[cnt].v=0;}int isap(int ss,int tt){ int mn,u(ss),i,ans(0);gap[0]=T; for (int i=1;i<=T;i++) cur[i]=point[i]; while (dis[ss]<=T){ f=false; for (i=cur[u];i;i=next[i]) if (e[i].v&&dis[e[i].en]+1==dis[u]){f=true;cur[u]=i;break;} if (f){ pre[u=e[i].en]=i; if (u==tt){ mn=INF; for (i=tt;i!=ss;i=e[pre[i]].st) mn=min(mn,e[pre[i]].v); ans+=mn; for (i=tt;i!=ss;i=e[pre[i]].st) e[pre[i]].v-=mn,e[pre[i]^1].v+=mn; u=ss; } } else{ gap[dis[u]]--;if (!gap[dis[u]]) return ans; for (mn=T,i=point[u];i;i=next[i]) if (e[i].v) mn=min(mn,dis[e[i].en]); gap[dis[u]=mn+1]++;cur[u]=point[u]; if (u!=ss) u=e[pre[u]].st; } } return ans;}int F(int x,int y){return (x-1)*q+y;}int cal(int x,int y,int z){return (x-1)*p*q+F(y,z);}int main(){ scanf("%d%d%d",&p,&q,&r);scanf("%d",&d); int t=p*q*r;T=p*q*r+2+p*q; for (int i=1;i<=r;i++) for (int j=1;j<=p;j++) for (int k=1;k<=q;k++) scanf("%d",&a[i][j][k]); for (int i=1;i<=r;i++) for (int j=1;j<=p;j++) for (int k=1;k<=q;k++){ if (i==1) add(cal(i,j,k)+1,T,INF); if (i==r) add(t+F(j,k)+1,cal(i,j,k)+1,a[i][j][k]); else add(cal(i+1,j,k)+1,cal(i,j,k)+1,a[i][j][k]); } for (int i=1;i<=p;i++) for (int j=1;j<=q;j++) add(1,F(i,j)+1+t,INF); for (int i=1;i<=r;i++) for (int j=1;j<=p;j++) for (int k=1;k<=q;k++) for (int l=0;l<4;l++){ int xx=j+dx[l],yy=k+dy[l],zz=i+d; if (xx<1||xx>p||yy<1||yy>q||zz<1||zz>r) continue; add(cal(i,j,k)+1,cal(zz,xx,yy)+1,INF); } cout<<isap(1,T)<<endl;}
0 0
- 【bzoj3144】【HNOI2013】【切糕】【最小割】
- 【BZOJ3144】[Hnoi2013]切糕【最小割】
- [BZOJ3144][HNOI2013]切糕 最小割
- bzoj3144: [Hnoi2013]切糕 DINIC最小割
- [BZOJ3144][Hnoi2013]切糕(最小割)
- [bzoj3144] [HNOI2013]切糕 网络流最小割
- [BZOJ3144][HNOI2013]切糕(最小割)
- bzoj3144 [Hnoi2013]切糕(最小割)
- BZOJ3144【HZNOI2013】切糕 <最小割>
- BZOJ3144【HNOI2013】切糕
- bzoj3144: [Hnoi2013]切糕
- bzoj3144【HNOI2013】切糕
- [BZOJ3144][HNOI2013]切糕
- [bzoj3144]【HNOI2013】切糕
- BZOJ3144: [Hnoi2013]切糕
- BZOJ3144: [Hnoi2013]切糕
- BZOJ3144: [Hnoi2013]切糕
- [题解]bzoj3144(HNOI2013)切糕
- Standup Timer 学习总结之一 —— MVC模式
- java中的匿名内部类总结
- pyspider创建淘女郎图片爬虫任务-运行流程解析
- Redis学习笔记(三)java redis 基本操作
- 电脑无法登陆ftp
- 【bzoj3144】【HNOI2013】【切糕】【最小割】
- Android学习笔记之AndroidManifest.xml文件解析
- 大型网站优化建议
- 字典解析
- android 远程访问tomcat工程中的xml
- TextView
- iOS程序-UITableView分组展示数据 - 纯手写代码
- LeetCode 3 Longest Substring Without Repeating Characters
- pyspider总结