博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【刷题】BZOJ 3144 [Hnoi2013]切糕
阅读量:5243 次
发布时间:2019-06-14

本文共 3091 字,大约阅读时间需要 10 分钟。

Description

1(6).jpg

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

Solution

拆成 \(R\) 层点,源点向第一层连边,最后一层向汇点连边

中间每一层 \(i\) 号点向下一层的 \(i\) 号点连边,流量为不和谐度
那么这样每一个纵轴就只会被切一个地方,满足题目要求
对于特殊限制,我们只要在被限制的点往上 \(D\) 层的四周的点连流量为 \(inf\) 的边即可,这样限制了四周的纵轴不能在 往上\(D\) 层之上切
最小割就代表切开,直接跑就好了

#include
#define ui unsigned int#define ll long long#define db double#define ld long double#define ull unsigned long longconst int MAXP=50+5,MAXN=64000+10,MAXM=MAXN*5+10,inf=0x3f3f3f3f;int P,Q,R,D,e=1,beg[MAXN],cur[MAXN],G[MAXP][MAXP][MAXP],level[MAXN],vis[MAXN],clk,s,t,to[MAXM<<1],nex[MAXM<<1],cap[MAXM<<1],dr[4][2]={
{0,1},{1,0},{-1,0},{0,-1}};std::queue
q;template
inline void read(T &x){ T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w;}template
inline void write(T x,char ch='\0'){ if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch);}template
inline void chkmin(T &x,T y){x=(y
inline void chkmax(T &x,T y){x=(y>x?y:x);}template
inline T min(T x,T y){return x
inline T max(T x,T y){return x>y?x:y;}inline int id(int x,int y,int z){ return (z-1)*P*Q+(x-1)*Q+y;}inline void insert(int x,int y,int z){ to[++e]=y; nex[e]=beg[x]; beg[x]=e; cap[e]=z; to[++e]=x; nex[e]=beg[y]; beg[y]=e; cap[e]=0;}inline bool bfs(){ memset(level,0,sizeof(level)); level[s]=1; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); for(register int i=beg[x];i;i=nex[i]) if(cap[i]&&!level[to[i]])level[to[i]]=level[x]+1,q.push(to[i]); } return level[t];}inline int dfs(int x,int maxflow){ if(x==t||!maxflow)return maxflow; vis[x]=clk; int res=0; for(register int &i=cur[x];i;i=nex[i]) if((vis[x]^vis[to[i]])&&cap[i]&&level[to[i]]==level[x]+1) { int f=dfs(to[i],min(cap[i],maxflow)); res+=f; cap[i]-=f; cap[i^1]+=f; maxflow-=f; if(!maxflow)break; } return res;}inline int Dinic(){ int res=0; while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf); return res;}int main(){ read(P);read(Q);read(R);read(D); for(register int k=1;k<=R;++k) for(register int i=1;i<=P;++i) for(register int j=1;j<=Q;++j)read(G[i][j][k]); s=P*Q*R+1,t=s+1; for(register int i=1;i<=P;++i) for(register int j=1;j<=Q;++j) for(register int k=1;k<=R;++k) { if(k==1)insert(s,id(i,j,k),inf); if(k!=R)insert(id(i,j,k),id(i,j,k+1),G[i][j][k]); else insert(id(i,j,k),t,G[i][j][k]); } for(register int k=D+1;k<=R;++k) for(register int i=1;i<=P;++i) for(register int j=1;j<=Q;++j) for(register int p=0;p<4;++p) { int dx=i+dr[p][0],dy=j+dr[p][1]; if(dx<1||dx>P||dy<1||dy>Q)continue; insert(id(i,j,k),id(dx,dy,k-D),inf); } write(Dinic(),'\n'); return 0;}

转载于:https://www.cnblogs.com/hongyj/p/9417756.html

你可能感兴趣的文章
Python函数(一)之杵臼之交
查看>>
关于将qt作为max插件ui库所遇到的困难
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
ASP.NET WebApi 基于OAuth2.0实现Token签名认证
查看>>
SendMail与Postfix的架构备忘
查看>>
paip.mysql 性能测试 报告 home right
查看>>
Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216 java c# php js.docx...
查看>>
283. Move Zeroes把零放在最后面
查看>>
我的函数说明风格
查看>>
ssh 简介
查看>>
26.无向网邻接表类
查看>>
Visual Studio Code 打开.py代码报Linter pylint is not installed解决办法
查看>>
洛谷 p1352 没有上司的舞会 题解
查看>>
Python 数据类型
查看>>
Task 与 Activity
查看>>
Google Guava学习笔记——简介
查看>>
历时八年,HTML5 标准终于完工了
查看>>
17.树的子结构
查看>>
D - Mike and strings
查看>>
C++:多维数组的动态分配(new)和释放(delete)
查看>>