← Все вопросы

Как доказать корректность алгоритма Куна через теорему Бержа об увеличивающих путях?

Задан 23 месяца назад768 просмотров2 ответа
8

Алгоритм Куна я запрограммировал, он работает. Но на устном этапе/в разборе нужно доказать, что он даёт именно максимальное паросочетание. Все ссылаются на «теорему Бержа об увеличивающих путях». Как звучит теорема и как из неё следует корректность Куна?

2 ответа

14
✓ Принятый ответ — помог автору

Увеличивающий путь для паросочетания MM — это простой путь, который начинается и заканчивается в непокрытых (свободных) вершинах и чередует рёбра «не в MM / в MM / не в MM / ...». Если такой путь есть, его можно «инвертировать» (поменять статус каждого ребра вдоль пути) — рёбер из MM станет на 1 больше.

Теорема Бержа: паросочетание MM максимально тогда и только тогда, когда в графе нет увеличивающего пути относительно MM.

Набросок доказательства. (⇒\Rightarrow) Если увеличивающий путь есть, инвертируем его и получаем большее паросочетание — значит MM не было максимальным. (⇐\Leftarrow) Пусть MM не максимально, и есть большее M′M'. Рассмотрим симметрическую разность M⊕M′M \oplus M' — она состоит из путей и циклов, где рёбра MM и M′M' чередуются. Так как ∣M′∣>∣M∣|M'| > |M|, найдётся путь, где рёбер M′M' больше — а это и есть увеличивающий путь относительно MM. Противоречие.

Корректность Куна. Кун, обрабатывая левые вершины по очереди, для каждой ищет увеличивающий путь (DFS, чередующий свободные рёбра и рёбра паросочетания). Он находит увеличивающий путь всякий раз, когда тот существует для текущей вершины. По завершении внешнего цикла ни для одной свободной левой вершины увеличивающего пути нет → по Бержу паросочетание максимально.

Ключевой факт, почему достаточно одного прохода по левым вершинам: однажды покрытая левая вершина остаётся покрытой до конца (паросочетание только растёт), поэтому пересматривать её не нужно.

5

Тонкий момент, который часто спрашивают на устном: почему DFS Куна корректно ищет именно чередующийся путь, хотя в коде нет явного «чередования»? Потому что переход из левой вершины идёт по свободному ребру в правую rr, а дальше — рекурсивный вызов tryKuhn(matchR[r]), то есть мы идём по ребру паросочетания от rr обратно в левую долю. Так автоматически выдерживается «свободное → matched → свободное → ...». Когда доходим до свободной правой вершины (matchR[r]==-1) — путь увеличивающий, инвертируем его рекурсивным присваиванием matchR[r]=v вдоль возврата из рекурсии.

Ваш ответ

, чтобы ответить на вопрос.