算法学习笔记(8.2): 上下界网络流

算法,学习,笔记,上下,网络 · 浏览次数 : 57

小编点评

**上下界网络流** 是一个网络流的变体,它关注流量的上界和下届的体现。上下界网络流是网络流的一种可行流,即任何从源点到汇点的路径上的流量总等于流出的流量。 **上下界网络流的特性:** * 下界网络是满流的,这意味着任何点流入和流出的量相等。 * 下界网络的每条边对应着流量下界。 **上下界网络的用途:** * 寻找有源汇上下界可行流。 * 确保网络中所有点的流量守恒。 **上下界网络的构造:** 1. **构造差界网络**:根据原图的结构构造出两张图。 2. **建立虚拟源点和汇点**:在差界网络中新建一个虚拟源点 \\(S'\\) 和虚拟汇点 \\(T'\\) 3. **考虑所有可能的情况**:在差界网络中考虑三种情况: * **流入大于流出**:如果源点吐出流量大于汇点吃掉的流量,则需要补齐多流入的部分。 * **流入小于流出**:如果源点吐出流量小于汇点吃掉的流量,则需要补齐多流出的部分。 * **流入等于流出**:如果源点吐出和汇点吃掉的流量相等,则不需要处理。 4. **从虚拟源点向虚拟汇点连一条容量为 \\(in(x) - out(x)\\) 的边**:如果源点流入流量为 \\(in(x)\\), 流出流量为 \\(out(x)\\)那么一共会出现三种情况: * **in(x) > out(x)**: 即流入大于流出。那么在差界网络中,我们需要补齐多流入的部分。 * **in(x) < out(x)**: 即流入小于流出,那么在差界网络中,我们需要补齐多流出的部分,所以,**x** 向虚拟汇点连一条容量为 \\(out(x) - in(x)\\) 边。 * **in(x) = out(x)**: 即流入等于流出,此时不需要处理。 5. **修改后的差界网络在保证下界网络的流量守恒之后,我们在修改过的差界网络上从 \\(S'\\) 到 \\(T'\\) 跑一次最大流,把每一条在原图上的边的流量加回到下界网络中**。 6. **从源点与实际汇点间连一条流量为 \\(INF\\) 的边**:如果实际汇点 \\(T\\) 到源点 \\(S\\)间还有额外的流量,则在修改后的差界网络中再从 \\(S\\) 到 \\(T\\) 跑一次最大流即可形象一点,在跑 \\(S'\\) 到 \\(T'\\) 的最大流时并不一定榨干了 \\(S\\) 到 \\(T\\) 的剩余流量,所以还需要再榨一次 \\(inf\\) 的流量。 7. **原网络的最大流即是两次跑最大流的流量和模板题**。

正文

上下界网络流

前置知识以及更多芝士参考下述链接
网络流合集链接:网络流

上下界网络流是普通网络流的一种变体,对于网络流,我们不仅关注其流量的上界,下届同样有所体现。
题型大致有五种

  • 有源汇
  • 无源汇
  • 可行流
  • 最大流
  • 最小流

虽然听着挺唬人的……其实理解了也非常简单


无源汇可行流

这是上下界网络流的基础,也是最简单的一种

给定一个没有源点和汇点,每条边有上下界的流量网络,目的是求有没有一种可能的流使得流量守恒

流量守恒:每一个点流入和流出的量相等


考虑这样一个图

我们先画出两个图

稍后解释是什么,以及有什么用

下界网络:

以及差界网络:

我们根据原图原图结构构造出了两张图

下界网络每一条边对应着流量下界,差界网络的每一条边容量对应着原图流量上下界的差

我们希望两个网络流相加之后恰好是原图的一种可行流,这首先要求下界网络是满流的(可行流至少必须达到下界)

但是考虑到流量守恒,我们需要对下界网络上不平衡的结点在差界网络上进行处理

首先我们在下界网络中新建一个虚拟源点 \(S'\) 和虚拟汇点 \(T'\)

本文中虚拟的点都以 \('\) 结尾

接着考虑在下界网络中的一个点 \(x\), 我们假设其流入流量为 \(in(x)\), 流出流量为 \(out(x)\)

那么一共会出现三种情况:

  • \(in(x) \gt out(x)\) 即流入大于流出。那么在差界网络中,我们需要补齐多流入的部分。那么我们通过虚拟源点向点 \(x\) 连一条容量为 \(in(x) - out(x)\) 的边。

  • \(in(x) = out(x)\) 即流入等于流出,此时不需要处理

  • \(in(x) \lt out(x)\) 即流入小于流出,那么在差界网络中,我们需要补齐多流出的部分,所以,\(x\) 向虚拟汇点连一条容量为 \(out(x) - in(x)\) 边

通过上述处理之后,差界图就变为了:

左图为处理过的差界网络,右图为下界网络

在保证了下界网络的流量守恒之后,我们在修改过的差界网络上从 \(S'\) 到 \(T'\) 跑一次最大流,把每一条在原图上的边的流量加回到下界网络中,就是获得了一种可行流。

但是,总归是有不可行的时候:如果我们新建的附加边没有达到满流状态,表明在差网络没有办法补齐下界网络中的不守恒,也就是说,原网络中不存在可行流。

在实际中,我们并不需要建立下界网络,只需要对于查网络进行处理即可

在最后判断的时候只需要判断所有关于源点的附加边是否满流,或者所有关于汇点的附加边即可

有源汇上下界可行流

思考一下,在有源汇的网络流中,流是如何”流动“的

很明显,是从源点到汇点

也就是说,源点吐出流量,汇点吃到流量,且源点吐出和汇点吃掉的流量一定一是一样的

那么考虑我们如何将流量恒定的留在网络中?

很明显,我们把汇点吃掉的流量流回源点即可

换句话来说,我们只需要在实际汇点 \(T\) 到源点 \(S\) 连接一条流量为 \(INF\) 的边就行了

如此处理之后,我们就把源点和汇点处理成网络中的一般点了

接着我们就只需要把它与一般的无源汇图进行一样的处理即可

如何寻找可行流流量?

由于我们将源点的流量流回了汇点,所以实际流量就是我们新建的从汇点到源点的边上的流量

处理之后大致是这样的

有源汇上下界最大流

考虑我们在处理后的图中得到了一个可行流,但是从实际源点与实际汇点间还可能有额外的流量

注意一下,下面是在跑完第一次最大流的剩余网络的基础上进行操作

最小流亦是

所以我们把在差界网络新建的所有额外边的流量设为 \(0\)(相当于删除这些边)然后再从 \(S\) 到 \(T\) 跑一次最大流即可

形象一点,我们在跑 \(S'\) 到 \(T'\) 的最大流时并不一定榨干了 \(S\) 到 \(T\) 的剩余流量,所以还需要再榨一次 \gou

那么此时原网络的最大流即是两次跑最大流的流量和

模板题:Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流 - 洛谷

NOTICE: 在这种稠密图上跑最大流,还是必要当前弧优化的,不然会死的很惨……

有源汇上下界最小流

与最大流类似,但是不是榨干了,是把榨了的还回去 有种心虚的感觉

所以,同样处理所有新建的额外边,但是这次是从 \(T\) 到 \(S\) 跑一次最大流

可以看作把流量流回去

此时原网络的最小流即是两次最大流的流量差

作者有话说

如果我们在求最大或者最小流的时候采用的是ISAP算法,那么千万要记住,在删除边之后需要更改源点汇点重新跑一次BFS更新深度(其实不更新也没大问题,反正错了也不给钱是吧 _)


Update 2023.3.10 修复图片无法显示问题

与算法学习笔记(8.2): 上下界网络流相似的内容:

算法学习笔记(8.2): 上下界网络流

# 上下界网络流 [TOC] > 前置知识以及更多芝士参考下述链接 > 网络流合集链接:[网络流](https://www.cnblogs.com/jeefy/p/17050215.html) 上下界网络流是普通网络流的一种变体,对于网络流,我们不仅关注其流量的上界,下届同样有所体现。 题型大致有五

算法学习笔记(8): 网络流

# 网络流 > 网络流是一个博大精深的一个话题…… ## 箕(基)畚(本)知识 文章链接:[基本知识](https://www.cnblogs.com/jeefy/p/17050220.html) ## 网络最大流 文章链接:[网络最大流](https://www.cnblogs.com/jeefy

算法学习笔记(8.0): 网络流前置知识

网络流基础 网络流合集链接:网络流 网络 $G = (V, E)$ 实际上是一张有向图 对于图中每一条有向边 $(x, y) \in E$ 都有一个给定的容量 $c(x, y)$ 特别的,若 $(x,y) \notin E$ , 则 $c(x, y) = 0$ 图中还有两个指定的特殊结点,$S, T

算法学习笔记(8.1): 网络最大流算法 EK, Dinic, ISAP

网络最大流算法 EK, Dinic, ISAP 详解

OI-Wiki 学习笔记

算法基础 \(\text{Update: 2024 - 07 - 22}\) 复杂度 定义 衡量一个算法的快慢,一定要考虑数据规模的大小。 一般来说,数据规模越大,算法的用时就越长。 而在算法竞赛中,我们衡量一个算法的效率时,最重要的不是看它在某个数据规模下的用时,而是看它的用时随数据规模而增长的趋

算法学习笔记(6): 树链剖分

树链剖分 树链剖分是一个很神奇,但是在树上可以完成一些区间操作问题 简单来说,就是把一棵树分成一条条的链,通过维护链上的信息来维护整棵树的信息 基础知识可以参考我的另外一篇博客:算法学习笔记(5): 最近公共祖先(LCA) 这里假设你已经掌握了上述博客中的所有相关知识,并清晰了其背后的原理 性质?发

算法学习笔记(11): 原根

原根 此文相对困难,请读者酌情食用 在定义原根之前,我们先定义其他的一点东西 阶 通俗一点来说,对于 $a$ 在模 $p$ 意义下的阶就是 $a^x \equiv 1 \pmod p$ 的最小正整数解 $x$ 或者说,$a$ 在模 $p$ 意义下生成子群的阶(群的大小) 再或者说,是 $a$ 在模

算法学习笔记(30):Kruskal 重构树

Kruskal 重构树 这是一种用于处理与最大/最小边权相关的一个数据结构。 其与 kruskal 做最小生成树的过程是类似的,我们考虑其过程: 按边权排序,利用并查集维护连通性,进行合并。 如果我们在合并时,新建一个节点,其权值为当前处理的边的权值,并将合并的两个节点都连向新建的节点,那么就可以得

算法学习笔记(3.1): ST算法

ST表 在RMQ(区间最值)问题中,著名的ST算法就是倍增的产物。ST算法可以在 \(O(n \log n)\) 的时间复杂度能预处理后,以 \(O(1)\) 的复杂度在线回答区间 [l, r] 内的最值。 当然,ST表不支持动态修改,如果需要动态修改,线段树是一种良好的解决方案,是 \(O(n)\

C++算法之旅、09 力扣篇 | 常见面试笔试题(上)算法小白专用

算法学习笔记,记录容易忘记的知识点和难题。详解时空复杂度、50道常见面试笔试题,包括数组、单链表、栈、队列、字符串、哈希表、二叉树、递归、迭代、分治类型题目,均带思路与C++题解