[bzoj3144] [HNOI2013]切糕 网络流最小割

本文介绍了一道经典最小割模型题目,并详细解析了如何通过网络流算法解决该问题。主要内容包括:如何将点权转化为边权,构建图的具体步骤,以及Dinic算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经典的最小割模型,然而初学网络流并没有想出建图,看学长和大佬题解才明白。。。

将点权转化为边权,注意输入有r层点的权值,转化为边权有r+1层。

由源向第一层每个点建边,容量为INF,由第r+1层向汇建边,容量为INF。

由点(i,j,k)向(i,j,k+1)建边,容量为v[i][j][k]。

因为相邻纵轴上有高度限制,所以要把每一个点向比它高度小d的相邻四个点建边,容量为INF。

如下图所示


之后跑dinic即可


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define inf 10000000
using namespace std;
struct bian
{
  int qi,zhong,w,next;
};
bian c[1000000];
int n,m,r,d,jishu=0,hd,tl,ji=0,ying,xuan;
int v[50][50][50],num[50][50][50],head[100000],dep[100000],q[100000];
void add(int x,int y,int z)
{
  c[jishu].qi=x;
  c[jishu].zhong=y;
  c[jishu].w=z;
  c[jishu].next=head[x];
  head[x]=jishu++;
}
bool bfs()
{
  memset(dep,0,sizeof(dep));
  hd=tl=0;
  q[++tl]=0;
  dep[0]=1;
  while(hd<tl)
  {
    int op=q[++hd];
    for(int i=head[op];i!=-1;i=c[i].next)
    {
      if(c[i].w&&(!dep[c[i].zhong]))
      {
        dep[c[i].zhong]=dep[op]+1;
        q[++tl]=c[i].zhong;
        if(c[i].zhong==ying)
          return 1;
      }
    }
  }
  return 0;
}
int dfs(int op,int fw)
{
  if(op==ying)  return fw;
  int tmp=fw,k;
  for(int i=head[op];i!=-1;i=c[i].next)
  {
    if(c[i].w&&tmp&&dep[c[i].zhong]==dep[op]+1)
    {
      k=dfs(c[i].zhong,min(c[i].w,tmp));
      if(!k)
      {
        dep[c[i].zhong]=0;
        continue;
      }
      c[i].w-=k;
      c[i^1].w+=k;
      tmp-=k;
    }
  }
  return fw-tmp;
}
int main()
{
  freopen("nutcake.in","r",stdin);
  freopen("nutcake.out","w",stdout);
	memset(head,-1,sizeof(head));
  scanf("%d%d%d%d",&n,&m,&r,&d);
  xuan=0;ying=n*m*(r+1)+1;
  for(int i=1;i<=r;++i)
    for(int j=1;j<=n;++j)
      for(int k=1;k<=m;++k)
      {
        scanf("%d",&v[i][j][k]);
        num[i][j][k]=++ji;
      }
  for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
      num[r+1][i][j]=++ji;
  for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    {
      add(xuan,num[1][i][j],inf);
      add(num[1][i][j],xuan,0);
    }
  for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    {
		  add(num[r+1][i][j],ying,inf);
      add(ying,num[r+1][i][j],0);
    }
  for(int i=1;i<=r;++i)
    for(int j=1;j<=n;++j)
      for(int k=1;k<=m;++k)
      {
        add(num[i][j][k],num[i+1][j][k],v[i][j][k]);
        add(num[i+1][j][k],num[i][j][k],0);
      }
  for(int i=r+1;i>=d+1;--i)
    for(int j=1;j<=n;++j)
      for(int k=1;k<=m;++k)
      {
        add(num[i][j][k],num[i-d][j+1][k],inf);
        add(num[i-d][j+1][k],num[i][j][k],0);
        add(num[i][j][k],num[i-d][j-1][k],inf);
        add(num[i-d][j-1][k],num[i][j][k],0);
        add(num[i][j][k],num[i-d][j][k+1],inf);
        add(num[i-d][j][k+1],num[i][j][k],0);
        add(num[i][j][k],num[i-d][j][k-1],inf);
        add(num[i-d][j][k-1],num[i][j][k],0);
      }
  int shu=0;
  while(bfs())
    shu+=dfs(0,inf);
  printf("%d",shu);
  return 0;
}




                
内容概要:本文介绍了多种开发者工具及其对开发效率的提升作用。首先,介绍了两款集成开发环境(IDE):IntelliJ IDEA 以其智能代码补全、强大的调试工具和项目管理功能适用于Java开发者;VS Code 则凭借轻量级和多种编程语言的插件支持成为前端开发者的常用工具。其次,提到了基于 GPT-4 的智能代码生成工具 Cursor,它通过对话式编程显著提高了开发效率。接着,阐述了版本控制系统 Git 的重要性,包括记录代码修改、分支管理和协作功能。然后,介绍了 Postman 作为 API 全生命周期管理工具,可创建、测试和文档化 API,缩短前后端联调时间。再者,提到 SonarQube 这款代码质量管理工具,能自动扫描代码并检测潜在的质量问题。还介绍了 Docker 容器化工具,通过定义应用的运行环境和依赖,确保环境一致性。最后,提及了线上诊断工具 Arthas 和性能调优工具 JProfiler,分别用于生产环境排障和性能优化。 适合人群:所有希望提高开发效率的程序员,尤其是有一定开发经验的软件工程师和技术团队。 使用场景及目标:①选择合适的 IDE 提升编码速度和代码质量;②利用 AI 编程助手加快开发进程;③通过 Git 实现高效的版本控制和团队协作;④使用 Postman 管理 API 的全生命周期;⑤借助 SonarQube 提高代码质量;⑥采用 Docker 实现环境一致性;⑦运用 Arthas 和 JProfiler 进行线上诊断和性能调优。 阅读建议:根据个人或团队的需求选择适合的工具,深入理解每种工具的功能特点,并在实际开发中不断实践和优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值