E054. Нахождение потока в 图е, в котором у каждого ребра указано минимальное и максимальное значение потока

e-maxx algorithm original: C/C++ #algorithm #emaxx #flow #graph
题目文本会按所选界面语言从俄语翻译;代码保持不变。

Источник: e-maxx.ru/algo, страница PDF 155.

Пусть дан 图 G, в котором для каждого ребра помимо пропускной способности (максимального значения потока вдоль этого ребра) указано и минимальное значение потока, который должен проходить по этому ребру. Здесь мы рассмотрим две задачи: 1) it is required find произвольный поток, удовлетворяющий всем 约束м, и 2) it is required find minimum поток, удовлетворяющий всем 约束м.

解法 задачи 1

Обозначим через Li минимальную величину потока, которая может проходить по i-му ребру, а через Ri - его максимальная величина. Произведём в 图е следующие изменения. Добавим новый исток S' и сток T'. Рассмотрим все рёбра, у которых Li отлично от нуля. Пусть i - номер такого ребра. Пусть концы этого ребра (ориентированного) - это вершины Ai и Bi. Добавим edge (S', Bi), у которого L = 0, R = Li, добавим edge (Ai, T'), у которого L = 0, R = Li, а у самого i-го ребра положим Ri = Ri - Li, а Li = 0. Наконец, добавим в 图 edge из T в S (старых стока и истока), у которого L = 0, R = INF. После выполнения этих преобразований все рёбра 图а будут иметь Li = 0, т.е. мы свели эту задачу к обычной задаче нахождения максимального потока (но уже в модифицированном 图е с новыми истоком и стоком) (чтобы понять, почему именно максимального - читайте нижеследующее 说明). Корректность этих преобразований понять сложнее. Неформальное 说明 такое. Каждое edge, у которого Li отлично от нуля, мы заменяем на два ребра: одно с пропускной способностью Li, а другое - с Ri-Li. Нам it is required find поток, который бы обязательно насытил первое edge из этой пары (т.е. поток вдоль этого ребра должен быть равен Li); второе edge нас волнует меньше - поток вдоль него может быть любым, лишь бы он не превосходил его пропускной способности. Итак, нам it is required find такой поток, который бы обязательно насытил некоторое множество рёбер. Рассмотрим каждое такое edge, и выполним такую операцию: подведём к его концу edge из нового истока S', подведём edge из его начала к стоку T', само edge удалим, а из старого стока T к старому истоку S проведём edge бесконечной пропускной способности. Этими действиями мы проимитируем тот факт, что это edge насыщено - из ребра будет вытекать Li единиц потока (мы имитируем это с помощью нового истока, который подаёт на конец ребра нужное количество потока), а втекать в него будет опять же Li единиц потока (но вместо ребра этот поток попадёт в новый сток). Поток из нового истока протекает по одной части 图а, дотекает до старого стока T, из него протекает в старый исток S, затем течёт по другой части 图а, и наконец приходит к началу нашего ребра, и попадает в новый сток T'. Т.е., если мы найдём в этом модифицированном 图е maximum поток (и в сток попадёт нужное количество потока, т.е. сумма всех значений Li - иначе величина потока будет меньше, и ответа попросту не существует), то мы одновременно найдём поток в исходном 图е, который будет удовлетворять все 约束м минимума, и, разумеется, всем 约束м максимума.

解法 задачи 2

Заметим, что по ребру из старого стока в старый исток с пропускной способностью INF протекает весь старый поток, т. е. пропускная способность этого ребра влияет на величину старого потока. При достаточно большой величине пропускной способности этого ребра (т.е. INF) старый поток ничем не ограничен. Если мы будем уменьшать пропускную способность, то и, начиная с некоторого момента, будет уменьшаться и величина старого потока. Но при слишком малом значении величина потока станет недостаточной, чтобы обеспечить выполнение ограничений (на минимальное значение потока вдоль рёбер). Очевидно, здесь можно применить бинарный поиск по значению INF, и find такое её наименьшее значение, при котором все 约束 ещё будут удовлетворяться, но старый поток будет иметь минимальное значение.

C# 解法

自动草稿,提交前请检查
// C# draft for: Нахождение потока в графе, в котором у каждого ребра указано минимальное и максимальное значение потока
// Original e-maxx article has no compact code listing in the extracted PDF text.

C++ 解法

匹配/原始
// C++ source for: Нахождение потока в графе, в котором у каждого ребра указано минимальное и максимальное значение потока
// Compact code block was not extracted from this article.

Java 解法

自动草稿,提交前请检查
// Java draft for: Нахождение потока в графе, в котором у каждого ребра указано минимальное и максимальное значение потока
// Original e-maxx article has no compact code listing in the extracted PDF text.

Материал разбит как 算法ическая 题目: изучить постановку, понять асимптотику и реализовать 算法 на выбранном языке.

Vacancies for this task

活跃职位 with overlapping task tags are 已显示.

所有职位
目前还没有活跃职位。