Алгоритм Форда-Фалкерсона для поиска максимального паросочетания — различия между версиями
(→Литература) |
(→Алгоритм) |
||
Строка 1: | Строка 1: | ||
− | == | + | ==Идея алгоритма== |
− | Пусть дан двудольный граф <tex>G(V, E)</tex> и требуется найти [[Теорема о максимальном паросочетании и дополняющих цепях|максимальное паросочетание]] в нём. | + | Пусть дан двудольный граф <tex>G(V, E)</tex> и требуется найти [[Теорема о максимальном паросочетании и дополняющих цепях|максимальное паросочетание]] в нём. Обозначим доли исходного графа как <tex>L</tex> и <tex>R</tex>. Построим граф <tex>G'(V', E')</tex> следующим образом: |
− | <tex>V' = V \cup \{s, t\}</tex> | + | <tex>V' = V \cup \{s, t\}</tex> (т.е. добавим две новые вершины <tex>s</tex> и <tex>t</tex>) |
− | + | <tex>E' = \{(s,u): u \in L\} \cup \{(u, v): u \in L, v \in R\} \cup \{(v, t): v \in R\} </tex> (проведем ребра из <tex>s</tex> в каждую вершину <tex>L</tex>, и из каждой вершины <tex>R</tex> в <tex>t</tex>). | |
− | # Будем искать путь из <tex>s</tex> в <tex>t</tex> поиском в глубину. | + | Изначально максимальное паросочетание пусто. |
+ | # Будем искать в графе <tex>G'</tex> путь из <tex>s</tex> в <tex>t</tex> поиском в глубину. | ||
# Если путь найден, инвертируем все рёбра на пути. | # Если путь найден, инвертируем все рёбра на пути. | ||
# Если путь не был найден, значит текущее паросочетание является максимальным, и алгоритм завершает работу. Иначе переходим к пункту 1. | # Если путь не был найден, значит текущее паросочетание является максимальным, и алгоритм завершает работу. Иначе переходим к пункту 1. | ||
В любой момент времени текущим паросочетанием будет множество рёбер, направленных из <tex>R</tex> в <tex>L</tex>. | В любой момент времени текущим паросочетанием будет множество рёбер, направленных из <tex>R</tex> в <tex>L</tex>. | ||
− | |||
− | |||
− | |||
==Псевдокод== | ==Псевдокод== |
Версия 23:53, 23 декабря 2011
Идея алгоритма
Пусть дан двудольный граф максимальное паросочетание в нём. Обозначим доли исходного графа как и . Построим граф следующим образом:
и требуется найти(т.е. добавим две новые вершины и )
(проведем ребра из в каждую вершину , и из каждой вершины в ).
Изначально максимальное паросочетание пусто.
- Будем искать в графе путь из в поиском в глубину.
- Если путь найден, инвертируем все рёбра на пути.
- Если путь не был найден, значит текущее паросочетание является максимальным, и алгоритм завершает работу. Иначе переходим к пункту 1.
В любой момент времени текущим паросочетанием будет множество рёбер, направленных из
в .Псевдокод
bool dfs(x)
if vis[x]
return false
vis[x] = true
for
if py[y] = -1
py[y] = x
px[x] = y
return true
else if dfs(py[y])
py[y] = x
px[x] = y
return true
return false
px[] = -1
py[] = -1
while (changed)
changed = false
vis[] = false
for
if (px[x] == -1)
if dfs(x)
changed = true