您的位置:首页 > 其它

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

2017-07-30 21:47 316 查看
一开始一脸懵逼后来发现,他不就是割吗,我们只要满足条件就割就行了,于是我们把他连了P*Q*R条边,然而我们要怎样限制D呢?我们只要满足对于任意相邻的两条路,只要其有个口大于D就不行就好了因此我们只要把每个点向离他D距离的下面的店连一条Inf连线就可以啦,因此我们就满足了一定是所有相邻的路径上存在不超过距离D的缺口,由于满足这条性质因此至少存在一层两两之间距离不超过D的膜因此最终答案一定是每条路上割一个,因此就让他跑去把!

#include <cstdio>
#include <cstring>
#define N 50
#define LL 8000000
#define r register
#define Inf 0x7f7f7f7f
using namespace std;
inline int read()
{
r int sum=0;
r char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')
{
sum=(sum<<1)+(sum<<3)+ch-'0';
ch=getchar();
}
return sum;
}
struct VIA
{
int to,next,f;
}c[LL];
int head[N*N*N],t=1;
int q[N*N*N],top,tail,deep[N*N*N],Hash

;
int a

,S,T;
inline void add(int x,int y,int z)
{
c[++t].to=y;
c[t].next=head[x];
head[x]=t;
c[t].f=z;
}
inline bool bfs()
{
memset(deep,0,sizeof(deep));
deep[S]=1;
q[1]=S;
top=tail=1;
while(top<=tail)
{
r int x=q[top++];
if(x==T)return 1;
for(int i=head[x];i;i=c[i].next)
if(c[i].f&&deep[c[i].to]==0)
{
deep[c[i].to]=deep[x]+1;
q[++tail]=c[i].to;
}
}
return 0;
}
int dfs(int x,int v)
{
if(x==T||!v)return v;
r int ret=0;
for(r int i=head[x];i;i=c[i].next)
if(c[i].f&&deep[c[i].to]==deep[x]+1)
{
r int f=dfs(c[i].to,c[i].f<v?c[i].f:v);
v-=f,ret+=f,c[i].f-=f,c[i^1].f+=f;
if(!v)break;
}
if(!ret)deep[x]=-1;
return ret;
}
inline int dinic()
{
r int ans=0;
while(bfs())ans+=dfs(S,Inf);
return ans;
}
int L,W,H,D;
int main()
{
L=read(),W=read(),H=read(),D=read();
S=L*W*H+1,T=S+1;
for(r int i=1;i<=H;++i)
for(r int j=1;j<=L;++j)
for(r int k=1;k<=W;++k)
a[j][k][i]=read(),Hash[j][k][i]=(i-1)*L*W+(j-1)*W+k;
if(H!=1)
{
for(r int i=1;i<=L;++i)
for(r int j=1;j<=W;++j)
{
add(S,Hash[i][j][1],a[i][j][1]),add(Hash[i][j][1],S,0);
for(r int k=2;k<H;++k)
add(Hash[i][j][k-1],Hash[i][j][k],a[i][j][k]),add(Hash[i][j][k],Hash[i][j][k-1],0);
add(Hash[i][j][H-1],T,a[i][j][H]),add(T,Hash[i][j][H-1],0);
if(H<=1+D)continue;
if(i!=1)
{
add(Hash[i][j][D],S,Inf),add(S,Hash[i][j][D],0);
for(r int k=D+1;k<H;++k)
add(Hash[i][j][k],Hash[i-1][j][k-D],Inf),add(Hash[i-1][j][k-D],Hash[i][j][k],0);
add(T,Hash[i-1][j][H-D],Inf),add(Hash[i-1][j][H-D],T,0);
}
if(i!=L)
{
add(Hash[i][j][D],S,Inf),add(S,Hash[i][j][D],0);
for(r int k=D+1;k<H;++k)
add(Hash[i][j][k],Hash[i+1][j][k-D],Inf),add(Hash[i+1][j][k-D],Hash[i][j][k],0);
add(T,Hash[i+1][j][H-D],Inf),add(Hash[i+1][j][H-D],T,0);
}
if(j!=1)
{
add(Hash[i][j][D],S,Inf),add(S,Hash[i][j][D],0);
for(r int k=D+1;k<H;++k)
add(Hash[i][j][k],Hash[i][j-1][k-D],Inf),add(Hash[i][j-1][k-D],Hash[i][j][k],0);
add(T,Hash[i][j-1][H-D],Inf),add(Hash[i][j-1][H-D],T,0);
}
if(j!=W)
{
add(Hash[i][j][D],S,Inf),add(S,Hash[i][j][D],0);
for(r int k=D+1;k<H;++k)
add(Hash[i][j][k],Hash[i][j+1][k-D],Inf),add(Hash[i][j+1][k-D],Hash[i][j][k],0);
add(T,Hash[i][j+1][H-D],Inf),add(Hash[i][j+1][H-D],T,0);
}
}
}
else
{
for(r int i=1;i<=L;++i)
for(r int j=1;j<=W;++j)
add(S,T,a[i][j][1]),add(T,S,0);
}
printf("%d",dinic());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: