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

e-maxx algorithm original: C/C++ #algorithm #emaxx #graph
선택한 UI 언어에 맞게 문제 텍스트를 러시아어에서 번역합니다. 코드는 변경하지 않습니다.

Источник: 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 표시됨.

전체 채용
아직 활성 채용이 없습니다.