ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

网络流练习

2022-07-07 19:04:01  阅读:203  来源: 互联网

标签:费用 容量 石柱 练习 餐巾 网络 蜥蜴 inf


目录

网络流练习

若是一个点经过的次数有限制,则需要拆点

拆点的妙用博大精深

注:下文中 \(s\) 指超级源点,\(t\) 指超级汇点

这里是最大流dinic的代码和费用流EK的代码

最大流

P1231 教辅的组成

题意

现在有 \(a,b,c\) 三种东西,分别有 \(n1,n2,n3\) 个

告诉你 \(m1\) 组 \(a,b\) 的对应关系,\(m2\) 组 \(a,c\) 的对应关系

只有 \(a_i\) 同时对应 \(b_j\) 和 \(c_k\),\(a_i\) 才能和 \(b_j\) 与 \(c_k\) 配成一套

问在不重复的条件下最多可以配成几套

思路

很基础的最大流

由于 \(a\) 对应 \(b\) 和 \(c\) ,考虑建图时把所有 \(a\) 放中间 \(b,c\) 放两边

从 \(s\) 向所有 \(b\) 连一条容量为 \(1\) 的边,从所有 \(c\) 向 \(t\) 连一条容量为 \(1\) 的边

从所有 \(b\) 向所有 \(a\) 连一条容量为 \(1\) 的边,从所有 \(a\) 向所有 \(c\) 连一条容量为 \(1\) 的边

跑最大流就行

但是我 \(Wrong\ Answer\) 了 \(QAQ\)

这是因为 \(a\) 在中间,若是像下面一样会算两次:

so,我们把中间的所有 \(a\) 拆成两个点,加一条容量为 \(1\) 的边

最大流即为答案

P2472 蜥蜴

题意

在一个 \(r\) 行 \(c\) 列的网格地图中有一些高度不同的石柱,第 \(i\) 行 \(j\) 列的石柱高度为 \(h_{i,j}\)。

一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。

每行每列中相邻石柱的距离为 \(1\),蜥蜴的跳跃距离是 \(d\),即蜥蜴可以跳到平面距离不超过 \(d\) 的任何一个石柱上。

石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减 \(1\)(如果仍然落在地图内部,则到达的石柱高度不变)。

如果该石柱原来高度为 \(1\),则蜥蜴离开后消失,以后其他蜥蜴不能落脚。

任何时刻不能有两只蜥蜴在同一个石柱上。

思路

数据范围很小,考虑网络流

因为每个石柱都有经过次数限制,所以要位置 \(i\) 拆成点 \(i\) 和 \(i'\) ,且 \(i\) 和 \(i'\) 之间连一条容量为 \(h_i\) 的边

用 \(i\) 表示跳到了石柱 \(i\),\(i'\) 表示从 \(i\) 点开始跳向别的石柱

若是能从一个石柱 \(i\) 跳到另一个石柱 \(j\) ,那么就从 \(i'\) 向 \(j\) 连一条容量为 \(inf\) 的边

若是能从一个石柱 \(i\) 跳出边界,那么就从 \(i'\) 向 \(t\) 连一条容量为 \(inf\) 的边

我们可以假设最开始每只蜥蜴都不在石柱上,而是在源点 \(s\)

然后从 \(s\) 向每个蜥蜴初始位置 \(i\) 连一条容量为 \(1\) 的边,表示一只蜥蜴

这样就可以巧妙地解决这个问题

最大流 \(maxflow\) 表示的是最多有多少只蜥蜴能跳走

记录蜥蜴总数 \(sum\),跑一遍网络流,最终结果为 \(sum-maxflow\)

最小割

P4313 文理分科

题意

有 \(n\times m\) 个人,每个人要么选文科,要么选理科

第 \(i\) 行 \(j\) 列的人选文科可以获得快乐值 \(art_{i,j}\),选理科可以获得快乐值 \(sci_{i,j}\)

若是一个人选的文科且上下左右的人都是文科,他可以获得额外快乐值 \(sameart_{i,j}\)

若是一个人选的理科且上下左右的人都是理科,他可以获得额外快乐值 \(samesci_{i,j}\)

求这些人的快乐值总和最大是多少

思路

非 \(A\) 即 \(B\) ,典型的最小割

先不考虑额外快乐值

在集合 \(S\) 中表示选文科,在集合 \(T\) 中表示选理科

从 \(s\) 向点 \((i,j)\) 连容量为 \(art_{i,j}\) 的边,从点 \((i,j)\) 向 \(t\) 连容量为 \(sci_{i,j}\) 的边

这样求最小割,割掉最少不要的快乐值,剩下的就是答案

考虑额外快乐值

我们新建一个节点 \(x\) 对应点 \((i,j)\) 的文科额外快乐值,从 \(s\) 向点 \(x\) 连容量为 \(sameart_{i,j}\) 的边

考虑上下左右及自己都必须选文科,因此从 \(x\) 向 \((i,j)\),\((i-1,j)\),\((i+1,j)\),\((i,j-1)\),\((i,j+1)\) 都连一条容量为 \(inf\) 的边

显然这五条边是不会被割掉的

因此若是这五个点中有两个点不在一个集合内,就必须要断掉它们之间的联系,因为 \(x\) 把它们连在一起了

此时不能割容量为 \(inf\) 的边,就只能割容量为 \(sameart_{i,j}\) 的边

理科的同理,我们新建一个节点 \(y\) 对应点 \((i,j)\) 的理科额外快乐值,从 \(y\) 向点 \(t\) 连容量为 \(samesci_{i,j}\) 的边

从 \((i,j)\),\((i-1,j)\),\((i+1,j)\),\((i,j-1)\),\((i,j+1)\) 向 \(x\) 都连一条容量为 \(inf\) 的边

根据最小割=最大流

跑一边 \(dinic\) 得到最大流 \(maxflow\),最终的答案是 \(all\_happiness-maxflow\)

P2762 太空飞行计划问题

题意

给定一张图,有左侧的点和右侧的点,左侧的点点权为正(对应试验),右侧的点点权为负(对应器材),如果选择了左侧的某个点就必须要选右边的一部分点。要求最大化点权和。

思路

若是左侧的点需要右侧的点,则连一条从左侧的点向右侧的点的有向边,这样问题就转换为:

给定一个有向无环图,点有点权,选择一个子图,满足子图上如果选择了一个点就必须选择它后继的所有点。最大化点权和。

这是一个经典最小割问题,叫做最大权闭合子图问题

建图操作如下:

从 \(s\) 向所有正权值的点连一条权值为点权的边,从所有负权值的店向 \(t\) 连一条权值为点权绝对值的边

保留原图中所有的边且容量为正无穷

则原图中最大点权和为原图中正点权权值和减最小割

\(S\) 包含所有要的点,\(T\) 包含所有不要的点

最小割割去的边必然与 \(s\) 或 \(t\) 相邻,因为其他的边容量均为 \(inf\)

当我们选择要一个正权值点的时候,必然会将其放入集合 \(S\),这样就会割掉与其相连的负权值点与 \(t\) 的连边,这时候割去了需要减去的值

当我们选择不要一个正权值点的时候,必然会将其放入集合 \(T\),这样就会割掉其与 \(s\) 相连的边,这时候割去了需要减去的值

这样求得的割就是原图正点权和需要减去的部分,最小割就能减的最少,这样点权和最大

P3227 切糕

题意

你在切一个蛋糕,蛋糕每个点有一个非负不和谐值 \(v\),切蛋糕的规则如下:

首先将每一个竖列的坐标用 \((x,y)\) 表示,数列上的点就是 \((x,y,z)\)

每次在每一数列选择一个点

对于数列 \((x,y)\) 我们选的点高度记作 \(f(x,y)\),那选的点坐标即为 \((x,y,f(x,y))\)

定义:竖列 \((x,y)\) 的相邻竖列坐标可表示为 \((x-1,y)\) \((x+1,y)\) \((x,y-1)\) \((x,y+1)\)

选点坐标时有一个限制:每一个竖列选的坐标 \((x,y)\) 与其相邻的竖列 \((a,b)\) 坐标高度差不超过 \(D\)

即 \(|f(x,y)-f(a,b)|\le D\)

现在求 \(\min\sum v[x][y][f(x,y)]\)

思路

先去掉高度差不超过 \(D\) 的条件,那么这就变成了一个求最小割的题目

我们直接把每一个竖列的所有点依次相连,容量为 \(v\) ,且从 \(s\) 连一条到这列起点,容量为 \(inf\) 的边,从这列终点连一条到 \(t\),容量为 \(inf\) 的边

但是还有高度差不超过 \(D\) 的条件,所以考虑让建好的网络中即使割掉高度差超过 \(D\) 的地方也无影响

于是我们就只需要从 \((i,j,k)\) 向 \((i\pm 1,j,k-D)\) 和 \(i,j\pm 1,k-D\) 连一条容量为 \(inf\) 的边

会发现这样的话即使割掉所有不合法的边仍能从 \(s\) 走到 \(t\)

画图模拟一下就可以理解了

最后的结果就是最小割

P2805 植物大战僵尸

题意

给定一个有向图,点有点权,选择一个子图,满足子图上如果选择了一个点就必须选择它之前的所有点。最大化点权和。

这里的之前所有点指从这个点出发,沿着反向边能跑到的所有点

思路

这个题无非就是这个的变式,是一个最大权闭合子图问题

但是这道题需要除去环,所以用拓扑排序

若是拓扑排序的队列为空但某个点入度仍大于 \(0\),则此点在一个环内,应该除去

而且这道题边是反的,因此跑完拓扑排序后把边反过来,跑一边网络流就行

具体做法不再叙述

费用流

P1251 餐巾计划问题

题意

一个餐厅在相继的 \(N\) 天里,每天需用的餐巾数不尽相同。

假设第 \(i\) 天需要 \(r_i\)块餐巾( \(i=1\sim N\))。餐厅可以购买新的餐巾,每块餐巾的费用为 \(p\) 分;或者把旧餐巾送到快洗部,洗一块需 \(m\) 天,其费用为 \(f\) 分,或者送到慢洗部,洗一块需 \(n\) 天(\(n>m\)),其费用为 \(s\) 分(\(s<f\))。

每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

试设计一个算法为餐厅合理地安排好 \(N\) 天中餐巾使用计划,使总的花费最小。

思路

每一天要处理两件事:准备干净餐巾以及处理脏餐巾

因此考虑把每个点拆成两个:早上和晚上,早上准备干净餐巾,晚上处理脏餐巾

建立一个源点 \(s\) 和一个汇点 \(t\)

  • 从 \(s\) 向第 \(i\) 天早上连一条容量为 \(inf\),费用为 \(p\) 的边,表示每一天可以购买任意多餐巾
  • 从第 \(i\) 天早上向汇点连一条容量为 \(r_i\),费用为 \(0\) 的边,表示第 \(i\) 天早上需要准备 \(r_i\) 的餐巾
  • 从源点向第 \(i\) 天晚上连一条容量为 \(r_i\),费用为 \(0\) 的边,表示第 \(i\) 天需要处理的脏餐巾数量
  • 从第 \(i\) 天晚上向第 \(i+1\) 天晚上连一条容量为 \(inf\),费用为 \(0\) 的边,表示第 \(i\) 天的脏餐巾留到第 \(i+1\) 天
  • 从第 \(i\) 天晚上向第 \(i+m\) 天早上连一条容量为 \(inf\),费用为 \(f\) 的边,表示快洗第 \(i\) 天的脏餐巾
  • 从第 \(i\) 天晚上向第 \(i+n\) 天早上连一条容量为 \(inf\),费用为 \(s\) 的边,表示慢洗第 \(i\) 天的脏餐巾

这样就做完了

P2153 晨跑

题意

有 \(n\) 个点,\(m\) 条边,起点为 \(1\),终点为 \(n\),每个边都有边权

求 \(1\sim n\) 最长有几条的路线(满足每次经过的点都不相同),且在这个情况下最少需要跑的路程是多少

思路

这不是最小费用最大流吗?

把原路线容量设为 \(1\) ,费用设为边权就可以求解

但是要满足每次经过的点都不相同

考虑拆点

把点 \(i\) 拆成 \(i\) 和 \(i+n\),从 \(i\) 向 \(i+n\) 连一条容量为 \(1\) 费用为 \(0\) 的边

这样就行了

答案分别是最大流和最小费用

P2469 星际竞速

题意

给一张 DAG,边有边权

你最开始不在图内

你可以耗费 \(a_i\) 的代价直接到达 \(i\) 点,也可以消耗 \(edge_{x\rightarrow y}\) 的代价从 \(x\) 走到 \(y\)

求使所有点都被走到的最小代价

思路

我们可以换一种理解方式:

每次都不在图内,然后瞬移到某一点 \(x\) ,然后再走

考虑费用流,让你在最大流的时候把每个点都遍历一遍,然后同时求出最小代价

从 \(s\) 点开始表示出发,走到 \(t\) 点表示结束

因此我们可以把所有边容量设为 \(1\),这样无论如何最大流的结果都不会变

若是你想在 \(x\) 点结束,你必定是位移到 \(x\) 或从某处走到 \(x\)

考虑拆点

我们把 \(i\) 点 拆成 \(i\) 和 \(i'\) ,然后从 \(s\) 向 \(i'\) 连费用为 \(a_i\) 的边,\(i'\) 向 \(t\) 连费用为 \(0\) 的边,\(s\) 向 \(i\) 连费用为 \(0\) 的边

若存在边 \(edge(i,j)\) \(i<j\),则从 \(i\) 向 \(j'\) 连费用为 \(edge(i,j)\) 的边

这样的话对于每一个点 \(i\) 对应的 \(i'\) 都会走向 \(t\) ,并且必定会由 \(s\) 或前面的点走到,可以更新最小答案

所以这种做法正确,最小费用即为答案

标签:费用,容量,石柱,练习,餐巾,网络,蜥蜴,inf
来源: https://www.cnblogs.com/into-qwq/p/16455752.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有