题目链接:点击查看

题目大意:给出一个数字梯形,一共有n行,第一行有m个数字,每行的数字个数逐行向下递增,现在要求从第一行的每个数字分别向下引出一条路径直到最后一层,共m条路径,现在问在以下三个条件下的最大权值和是多少:

  1. 从梯形的顶至底的 m 条路径互不相交
  2. 从梯形的顶至底的 m 条路径仅在数字结点处相交
  3. 从梯形的顶至底的 m 条路径允许在数字结点相交或边相交

分别输出以上三种情况的答案

题目分析:其实三种情况大同小异,本质都是冲着最大费用最大流去的,分别说一下每种情况的细节吧:

首先是第一种情况,也就是m条路径互不相交,意思就是不能有相交的边或相交的点,既然没有相交的点,我们可以拆点限流,让每个顶点拆成入点和出点,连一条流量为1,花费为点权的边,这样就起到了限流并且为答案贡献出花费的作用了,记得让点之间的连边也限流就好了:

  1. 源点->第一行的m个点,流量为1,花费为0
  2. 每个点的入点->每个点的出点,流量为1,花费为点权
  3. 每个点的出点->下一层可到达的点的入点,流量为1,花费为0
  4. 最后一行的n+m-1个点->汇点,流量为1,花费为0

然后是第二种情况,也就是只有点可以重复经过,因为点可以重复经过,所以大可不必拆点限流了,所以直接连边,不用分成入点和出点就行了,不过这样的话就需要将点权转移到边权上,类似于之前树链剖分的题目一样,将点权转移到边权上,我感觉不太直观,还不如直接拆点来的实在,所以我选择了仍然拆点操作,因为每个点可以重复经过了,故将入点到出点的流量改成无穷大就好了,这里有个小坑,就是最后一行的所有点也是可以重复经过的,所以记得将最后一行的点与汇点的连边的限流也取消:

  1. 源点->第一行的m个点,流量为1,花费为0
  2. 每个点的入点->每个点的出点,流量为无穷大,花费为点权
  3. 每个点的出点->下一层可到达的点的入点,流量为1,花费为0
  4. 最后一行的n+m-1个点->汇点,流量为无穷大,花费为0

最后就是第三种情况了,也就是点和边都可以重复经过,我们只需要将所有的限流都取消,即除了与源点相连的所有边的流量都改为无穷大就好了:

  1. 源点->第一行的m个点,流量为1,花费为0
  2. 每个点的入点->每个点的出点,流量为无穷大,花费为点权
  3. 每个点的出点->下一层可到达的点的入点,流量为无穷大,花费为0
  4. 最后一行的n+m-1个点->汇点,流量为无穷大,花费为0

三种建图方式,每次只需要建好边跑最大费用最大流就是答案了

还有一些细节需要注意一下,首先是这个题目的输入,题目说的只是有n行,第一行有m个数字,而并非是n*m的矩阵,所以我们应该开一个20*40的数组才够用,再就是我喜欢写函数来将点拆成入点和出点,其中每次都会加上有多少列用来防止重复,放到这个题目来说因为列是改变的,所以每次加上40才能更稳的通过,最后就是N和M有多少空间就开多大吧,因为这种题目的N和M都比较难算,干脆开大点当个快乐的莽夫多好

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e5+100;//点const int M=1e6+100;//边struct Edge
{int to,w,cost,next;
}edge[M];int head[N],cnt,maze[110][110],n,m,st=N-1,ed=st-1;void addedge(int u,int v,int w,int cost)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].cost=cost;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;edge[cnt].cost=-cost;edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],incf[N],pre[N];bool vis[N];bool spfa(int s,int t)
{memset(d,0xcf,sizeof(d));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));queue<int>q;q.push(s);vis[s]=true;incf[s]=inf;d[s]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;int cost=edge[i].cost;if(!w)continue;if(d[v]<d[u]+cost){d[v]=d[u]+cost;pre[v]=i;incf[v]=min(incf[u],w);if(!vis[v]){vis[v]=true;q.push(v);}}}}return pre[t]!=-1;
}int update(int s,int t)
{int x=t;while(x!=s){int i=pre[x];edge[i].w-=incf[t];edge[i^1].w+=incf[t];x=edge[i^1].to;}return d[t]*incf[t];
}void init()
{memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0;while(spfa(st,ed))ans+=update(st,ed);return ans;
}int get_id(int x,int y,int k)
{return (x-1)*(n+m)+y+k*(n+m)*(n+m);
}void build1()
{init();for(int i=1;i<=m;i++)addedge(st,get_id(1,i,0),1,0);for(int i=1;i<=n+m-1;i++)addedge(get_id(n,i,1),ed,1,0);for(int i=1;i<=n;i++){for(int j=1;j<=i+m-1;j++){addedge(get_id(i,j,0),get_id(i,j,1),1,maze[i][j]);if(i<n){addedge(get_id(i,j,1),get_id(i+1,j,0),1,0);addedge(get_id(i,j,1),get_id(i+1,j+1,0),1,0);}}}
}void build2()
{init();for(int i=1;i<=m;i++)addedge(st,get_id(1,i,0),1,0);for(int i=1;i<=n+m-1;i++)addedge(get_id(n,i,1),ed,inf,0);for(int i=1;i<=n;i++){for(int j=1;j<=i+m-1;j++){addedge(get_id(i,j,0),get_id(i,j,1),inf,maze[i][j]);if(i<n){addedge(get_id(i,j,1),get_id(i+1,j,0),1,0);addedge(get_id(i,j,1),get_id(i+1,j+1,0),1,0);}}}
}void build3()
{init();for(int i=1;i<=m;i++)addedge(st,get_id(1,i,0),1,0);for(int i=1;i<=n+m-1;i++)addedge(get_id(n,i,1),ed,inf,0);for(int i=1;i<=n;i++){for(int j=1;j<=i+m-1;j++){addedge(get_id(i,j,0),get_id(i,j,1),inf,maze[i][j]);if(i<n){addedge(get_id(i,j,1),get_id(i+1,j,0),inf,0);addedge(get_id(i,j,1),get_id(i+1,j+1,0),inf,0);}}}
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);scanf("%d%d",&m,&n);for(int i=1;i<=n;i++)for(int j=1;j<=i+m-1;j++)scanf("%d",&maze[i][j]);build1();printf("%d\n",solve(st,ed));build2();printf("%d\n",solve(st,ed));build3();printf("%d\n",solve(st,ed));return 0;
}

洛谷 - P4013 数字梯形问题(最大费用最大流+举一反三)相关推荐

  1. 洛谷 - P3356 火星探险问题(最大费用最大流+拆点+路径打印)

    题目链接:点击查看 题目大意:给出一个n*m的矩阵,每个点都有一个数字: 0:平坦无障碍 1:障碍 2:石块 现在在点(1,1)处有k个探测车,他们都要去往点(n,m)处,探测车只能向下或向右行驶,现 ...

  2. 洛谷 - P2770 航空路线问题(最大费用最大流+路径打印)

    题目链接:点击查看 题目大意:给出一个由n个点及m条边组成的无向图,现在要求从点1出发,到达点n,再回到点1,一路上经过尽可能多的点,并且保证除了起点和终点外的每个点至多只能经过一次,并输出路径 题目 ...

  3. 洛谷 - P1251 餐巾计划问题(最小费用最大流+思维建边)

    题目链接:点击查看 题目大意:给出n天每天所需要的新餐巾的数量,现在有多种方式可以获得新餐巾,问如何运营能使花费最少: 直接购买,花费为cost 将脏餐巾送到快洗部,需要洗t1天,花费为c1 将脏餐巾 ...

  4. 洛谷 - P4012 深海机器人问题(最大费用最大流)

    题目链接:点击查看 题目大意:给出一个n*m的矩阵,共有(n+1)*(m+1)条边,每条边都有一个权值,现在给出a个起点以及b个终点,问从怎样设计路线能让起点到终点的权值和最大,注意每条边的权值至多计 ...

  5. 洛谷 - P4016 负载平衡问题(最小费用最大流)

    题目链接:点击查看 题目大意:有n个仓库分布在一个环形的区域,现在每个仓库可以与相邻的两个仓库转移货物,问最少需要操作多少次才能让每个仓库的货物都达到平衡 题目分析:达到平衡的意思其实就是都等于平均值 ...

  6. 洛谷 P2053 [SCOI2007]修车 网络流 最小费用最大流 Dinic+Spfa

    题目链接: https://www.luogu.com.cn/problem/P2053 思路参考博客: https://www.luogu.com.cn/blog/a23333/solution-p ...

  7. 洛谷 P3381 【模板】最小费用最大流

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数\(N.M.S.T\) ...

  8. 洛谷 - P3980 [NOI2008]志愿者招募(最小费用最大流+思维建边)

    题目链接:点击查看 题目大意:现在有n天需要志愿者,每一天需要招募的人数是Ai个人,现在有m类志愿者,每类志愿者可以在[l,r]天内被招募,需要花费的代价为Ci,现在需要安排一种招募方式,可以使得总花 ...

  9. 洛谷P3381 【模板】最小费用最大流

    传送门 费用流板子 细节真多--一个边的flow和点的flow分不清--还有往回减流的时候应该减去flow[t]-- 1 //minamoto 2 #include<iostream> 3 ...

最新文章

  1. 类与对象与结构体的区别
  2. 报错笔记:cannot convert parameter 1 from 'char [1024]' to 'unsigned char *'
  3. java基础知识1---面向对象及final,finally,finalize区别
  4. 2021爱智先行者—(2)零基础APP开发实例
  5. 程序员如何才算真正的高效编程?
  6. 如何做WP的登录/注册功能
  7. (tip_修订0618)bmp 32位转24位
  8. 服务器无法分配系统页面缓冲池中的内存
  9. php探针作用,X 探针(刘海探针)一款开源又好用的PHP探针
  10. .CR2格式文件怎么快速批量转换成JPG等格式
  11. 【原】豆瓣电台桌面版插件开发——搜索插件
  12. layui中关于重置按钮不起作用的提醒
  13. 京东E卡查询绑定助手电脑版APP
  14. Java对上传的图片进行格式校验以及安全性校验
  15. 餐饮行业为什么要开发点餐app?
  16. 被假阀门坑过吗?如何辨别翻新阀门?
  17. 单片机C语言节日彩灯,单片机c语言节日彩灯控制器设计.docx
  18. 美团/饿了么外卖劵系统开发(现成系统源码)
  19. 阀门的开关方向_阀门的开关方向如何正确操作阀门
  20. 如果你把每一天都当作生命中最后一天去生活的话,那么有一天你会发现你是正确的

热门文章

  1. 关系型数据库设计规则
  2. MySQL高级 - 日志 - 二进制日志(row及日志删除)
  3. RabbitMQ队列持久化
  4. Spring中的Events
  5. Survivor区详解
  6. AOP 中必须明白的概念-通知(Advice)
  7. Executor家族的辨析
  8. SpringCloud:Hystrix 熔断机制(基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)
  9. linux拷贝文件到多个目录,怎么在 Linux 中复制文件到多个目录中
  10. oracle数据结构是什么意思,Oracle数据结构知多少(一)