题面:洛谷传送门 BZOJ传送门

最大流神题

把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边

源点$S$向第$1$层的点连边,第$R+1$层的点向$T$连边,流量均为$inf$

跑最大流,最大流的流量就是答案

因为每条纵轴都取了最小的$v$,被割掉的边就是最小的$v$所在的边

然而题目里还有限制,相邻两个纵轴取值的位置相差的距离不能超过$D$

如何处理这个限制呢?

每个点$(i,j,k)$向$(x,y,k-D)$连流量为$inf$的边,$(x,y)$是$(i,j)$相邻的纵轴

假设纵轴$(i,j)$的割点是$(i,j,k)$

如果$(x,y)$的割点在$(x,y,k-D)$下面,一定会有一条流量从纵轴$(i,j)$流到$(x,y)$里,然后向上流到汇点$T$

巧妙地解决了距离的限制问题

 #include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 67010
#define M1 400010
#define L1 45
using namespace std;
const int inf=0x3f3f3f3f; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
struct Edge{
int to[M1<<],nxt[M1<<],flow[M1<<],head[N1],cte;
void ae(int u,int v,int f)
{
cte++; to[cte]=v; nxt[cte]=head[u];
head[u]=cte; flow[cte]=f;
}
}e; int dep[N1],que[M1],cur[N1],n,m,h,D,hd,tl,S,T;
int bfs()
{
int x,j,v;
memset(dep,-,sizeof(dep)); memcpy(cur,e.head,sizeof(cur));
hd=,tl=; que[++tl]=S; dep[S]=;
while(hd<=tl)
{
x=que[hd++];
for(j=e.head[x];j;j=e.nxt[j])
{
v=e.to[j];
if( dep[v]==- && e.flow[j]> )
{
dep[v]=dep[x]+;
que[++tl]=v;
}
}
}
return dep[T]!=-;
}
int dfs(int x,int limit)
{
int j,v,flow,ans=;
if(!limit||x==T) return limit;
for(j=cur[x];j;j=e.nxt[j])
{
v=e.to[j]; cur[x]=j;
if( dep[v]==dep[x]+ && (flow=dfs(v,min(limit,e.flow[j]))) )
{
e.flow[j]-=flow; limit-=flow;
e.flow[j^]+=flow; ans+=flow;
if(!limit) break;
}
}
return ans;
}
int Dinic()
{
int mxflow=,j,v,ans=;
while(bfs())
mxflow+=dfs(S,inf);
return mxflow;
} int xx[]={-,,,},yy[]={,,,-};
int v[L1][L1][L1],id[L1][L1][L1];
inline int check(int x,int y){return (x<||y<||x>n||y>m)?:;} int main()
{
scanf("%d%d%d%d",&n,&m,&h,&D);
int i,j,k,x,y,w,p; e.cte=; S=; T=n*m*(h+)+;
for(k=;k<=h+;k++) for(i=;i<=n;i++) for(j=;j<=m;j++) id[k][i][j]=(k-)*n*m+(i-)*m+j;
for(k=;k<=h;k++) for(i=;i<=n;i++) for(j=;j<=m;j++)
{
w=v[k][i][j]=gint(), x=id[k][i][j];
e.ae(x,x+n*m,w), e.ae(x+n*m,x,);
if(k<=D) continue;
//x+=n*m;
for(p=;p<;p++)
{
if(!check(i+xx[p],j+yy[p])) continue;
y=id[k-D][i+xx[p]][j+yy[p]];
e.ae(x,y,inf); e.ae(y,x,);
}
}
for(i=;i<=n;i++) for(j=;j<=m;j++) e.ae(S,id[][i][j],inf), e.ae(id[][i][j],S,);
for(i=;i<=n;i++) for(j=;j<=m;j++) e.ae(id[h+][i][j],T,inf), e.ae(T,id[h+][i][j],);
printf("%d\n",Dinic());
return ;
}

最新文章

  1. Java正则速成秘籍(二)之心法篇
  2. css用clearfix清除浮动
  3. Install ssdb-rocks on CentOS 6
  4. 解决 border-radius 元素在应用了 transform 的子元素 时overflow:hidden 失效的问题
  5. MS 数据库存储过程加密解密
  6. c#入门实例
  7. 50个非常有用的PHP工具
  8. Jquery使用tbody编辑功能实现table输入计算功能
  9. VS 项目(c#)引用了 DLL文件,也写了Using,但是编译时提示:未能找到类型或命名空间名称
  10. http://localhost:8080/ 演出Oracle说明
  11. SQL Server AlwaysOn中的几个误区
  12. Dynamics CRM 构建IN查询
  13. 布局 android
  14. TensorRT&amp;Sample&amp;Python[yolov3_onnx]
  15. STM32L476RG_中断开发与实列
  16. 研发团队如何写好API接口文档
  17. TCGA样本命名详解
  18. Streaming SQL for Apache Kafka
  19. PAT B1034 有理数四则运算 (20 分)
  20. Docker_容器化gitlab

热门文章

  1. 公众号和app和web都是客户端,都可以对接一个后台
  2. HDU 3691
  3. [LeetCode]Wildcard Matching 通配符匹配(贪心)
  4. apple 团队电话
  5. 将Latex tex文档转换成 word文档(上)
  6. RDLC报表钻取空白页问题
  7. luogu1072 Hankson的趣味题
  8. udev详解【转】
  9. Linq的Except
  10. 国内物联网平台初探(五) ——机智云IoT物联网云服务平台及智能硬件自助开发平台