E065. Покрытие путями ориентированного ациклического 图а

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

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

Дан ориентированный ациклический 图

. it is required покрыть его наименьшим numberм путей, т.е. find наименьшее по мощности множество непересекающихся по vertexм простых путей, таких, что каждая vertex принадлежит какому-либо пути.

Сведение к двудольному 图у

Пусть дан 图

с

vertexми. Построим соответствующий ему двудольный 图

стандартным образом, т.е.:

в каждой доле 图а

будет по

вершин, обозначим их через

и

соответственно. Тогда для каждого ребра

исходного 图а

проведём соответствующее edge

.

Каждому ребру

соответствует одно edge

, и наоборот. Если мы рассмотрим в

любой

путь

, то ему ставится в соответствие набор

рёбер

. Более просто для понимания будет, если мы добавим "обратные" рёбра, т.е. образуем 图

из 图а

добавлением рёбер вида

. Тогда пути

в 图е

будет соответствовать путь

.

Обратно, рассмотрим любой путь

в 图е

, начинающийся в первой доле и заканчивающийся во второй

доле. Очевидно,

снова будет иметь вид

, и ему можно поставить

в соответствие в 图е

путь

. Однако здесь есть одна тонкость:

могло совпадать с

, поэтому путь

получился бы циклом. Однако по условию 图

ациклический, поэтому это вообще

невозможно (это единственное место, где используется ацикличность 图а

; тем не менее, на циклические

图ы описываемый здесь метод вообще нельзя обобщить).

Итак, всякому простому пути в 图е

, начинающемуся в первой доле и заканчивающемуся во второй, можно

поставить в соответствие простой путь в 图е

, и наоборот. Но заметим, что такой путь в 图е

—

это паросочетание в 图е

. Таким образом, любому пути из

можно поставить в соответствие

паросочетание в 图е

, и наоборот. Более того, непересекающимся путям в

соответствуют

непересекающиеся паросочетания в

. Последний шаг. Заметим, что чем больше путей есть в нашем наборе, тем меньше все эти пути содержат рёбер. А

именно, если есть

непересекающихся путей, покрывающих все

вершин 图а, то они вместе содержат

рёбер. Итак, чтобы минимизировать number путей, мы должны максимизировать number рёбер в них. Итак, мы свели задачу к нахождению максимального паросочетания в двудольном 图е

. После нахождения

этого паросочетания (см. 算法 Куна) мы должны преобразовать его в набор путей в

(это делается

тривиальным 算法ом, неоднозначностей здесь не возникает). Некоторые вершины могут остаться ненасыщенными паросочетанием, в таком случае в ответ надо добавить пути нулевой длины из каждой из этих вершин.

Взвешенный случай

Взвешенный случай не сильно отличается от невзвешенного, просто в 图е

на рёбрах появляются веса, и

it is required find уже паросочетание наименьшего веса. Восстанавливая ответ аналогично невзвешенному случаю, мы получим покрытие 图а наименьшим numberм путей, а при равенстве — наименьшим по стоимости.

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 已显示.

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