Хопкрофт — Карп
За проход находится сразу максимальный набор кратчайших увеличивающих путей. Проходов не больше корня из числа вершин.
2 мин
Алгоритм Куна ищет по одному увеличивающему пути за проход и стоит . На сетках, досках и графах ходов коня, где вершин под сотню тысяч, это уже опасно.
Хопкрофт и Карп заметили, что за один проход можно найти сразу максимальный набор непересекающихся кратчайших увеличивающих путей — и что таких проходов нужно не больше .
Почему проходов мало
Пусть после нескольких фаз кратчайший увеличивающий путь имеет длину . Известно, что после каждой фазы эта длина строго растёт. С другой стороны, если максимальное паросочетание больше текущего на , то симметрическая разность содержит непересекающихся увеличивающих путей, и хотя бы один из них короче .
Значит, после фаз до максимума остаётся не больше увеличений, и каждое даёт ещё одну фазу. Итого фаз по каждая.
Устройство фазы
Обход в ширину от всех свободных вершин левой доли по чередующимся рёбрам расставляет слои: — расстояние в чередующихся шагах. Если ни одной свободной вершины правой доли не достигли, паросочетание максимально.
Обход в глубину ищет увеличивающие пути, спускаясь строго по слоям: из разрешено идти в , только если . Найденный путь сразу применяется, а вершины, из которых пути нет, помечаются как бесполезные до конца фазы.
while (bfs()) { // слои
for (int u = 0; u < leftCount; u++) iterator[u] = start[u];
for (int u = 0; u < leftCount; u++)
if (matchLeft[u] == -1 && tryAugment(u)) size++;
}
Две детали реализации
Указатель текущего ребра. Массив iterator хранит, до какого ребра вершина уже просмотрена в этой фазе. Без него фаза перестаёт быть линейной: одна и та же вершина будет перебирать своих соседей заново на каждом спуске.
Обход в глубину стеком, а не рекурсией. Длина увеличивающего пути доходит до числа вершин; на графе из ста тысяч вершин рекурсия — это отказ по памяти, а не по времени, и найти его труднее.
Когда что писать
| вершин | рёбер | чем решать |
|---|---|---|
| до тысячи | любое | Кун без эвристик |
| до десятков тысяч | разреженный | Кун с жадным началом |
| сотни тысяч | любое | Хопкрофт — Карп |
| граф специально подобран против Куна | — | Хопкрофт — Карп |
Жадное начальное паросочетание полезно и здесь: оно уменьшает число фаз, ничего не ломая.