Алгоритм Куна для поиска максимального паросочетания

Материал из Викиконспекты
Версия от 21:34, 14 декабря 2010; 192.168.0.2 (обсуждение) (Сложность)
Перейти к: навигация, поиск
Теорема:
Если из вершины х не существует дополняющей цепи относительно паросочетания М, то если паросочетание М' получается из М изменением вдоль дополняющей цепи, то из х не существует дополняющей цепи в М'.
Доказательство:
[math]\triangleright[/math]
Доказательство от противного! Допустим, что из х появилась дополняющая цепь относительно M'. Рассмотрим изменения, которые мы внесли в М вдоль дополняющей цепи, чтобы получить паросочетание М'. В этой цепи все промежуточные вершины были насыщенными, а концы свободные. После изменения вдоль этой цепи все вершины, лежащие на этой цепи станут насыщенными. Тогда появившаяся дополняющая цепь должна проходить хотя бы через одну из концевых вершин в той дополняющей цепи, относительно которой вносили изменения, поскольку иначе такая же дополняющая цепь была и в паросочетании М. Однако поскольку в паросочетании М концевые вершины не насыщены, то из вершины х в паросочетании М есть все равно есть дополняющая цепь. Надо рассмотреть часть дополняющей цепи в М', ограниченную концом текущей дополняющей цепи и концом той дополняющей цепи, вдоль которой вносили изменения, такую что вершина х будет промежуточной. Легко заметить что в такой цепи все промежуточные вершины насыщенные, а концы свободны, поэтому она является дополняющей. Значит, мы пришли к противоречию, поскольку в паросочетании М нет дополняющих цепей из вершины х.
[math]\triangleleft[/math]

Алгоритм

Пусть дан двудольный граф [math]G(V, E)[/math] и требуется найти максимальное паросочетание в нём. Обозначим доли исходного графа как [math]L[/math] и [math]R[/math].
1) Просматриваем вершины [math]s[/math] из доли [math]L[/math].

2) Будем искать дополняющую цепь из [math]s[/math] поиском в глубину.

3) Если цепь найдена, инвертируем все ребра на этой цепи.

В любой момент времени текущим паросочетанием будет множество ребер, направленных из [math]R[/math] в [math]L[/math]. Корректность работы алгоритма следует из теоремы Бержа и доказанной выше теоремы.

Псевдокод

 bool  dfs(x):
   vis[x] = true
   for [math]xy \in E[/math]:
       k = py[y]
       if (k == -1) or ((not vis[k]) and (dfs(k))):
           py[y] = x
           return true
   return false
 Kuhn():
   py[] = -1
   for [math]s \in L[/math]:
       vis[] = false
       dfs(s)

Время работы

Итак, алгоритм Куна можно представить как серию из |[math]L[/math]| запусков обхода в глубину на всём графе. Следовательно, всего этот алгоритм исполняется за время [math]O(V E)[/math], что в худшем случае есть [math]O(V^3)[/math].

Литература