Понимание алгоритма Куна
Понадобилось составить описание алгоритма Куна. Посмотрите, пожалуйста, не ошибся ли я в понимании данного алгоритма.
Поочередно будем запускать обход в глубину из вершин левой доли, еще не насыщенных паросочетанием M. Таким образом, из каждой такой вершины будем пытаться построить M-чередующуюся цепь. Как только найдется увеличивающий относительно M путь, построим новое паросочетание из ребер цепи, не входящих в M.
В массив visitedKuhn записываются значения, отражающие «посещенность» вершин левой доли. Это нужно, чтобы обход в глубину не заходил дважды в одну вершину.
Массивы matchingLeft и matchingRight характеризуют текущее паросочетание. Каждая ячейка массива matchingLeft[v]=i содержит индекс вершины правой доли, с которой соединяется ребром соответствующая вершина левой доли с индексом v. Значение i=-1 говорит об отсутствии выбранного ребра, идущего из v в i.
В теле функции просматриваются все ребра, исходящие из вершины v, затем проверяется следующее:
- ведет ли ребро в ненасыщенную вершину правой доли i
- если эта вершина насыщена, можно ли построить увеличивающую цепь из соответствующей вершины matchingRight[i] (которая находится в левой доле).
Если выполняется одно из условий, мы можем утверждать, что нашли увеличивающую цепь. Тогда перенаправим ребро, инцидентное i, в вершину v, а затем вернем в основную программу результат true.
bool dfs_kuhn(int v)
{
if(visitedKuhn[v]) return false;
visitedKuhn[v]=true;
for(int i=0; i<N; i++)
if(matrix[v][i].weight==0 && (matchingRight[i]==-1 || dfs_kuhn(matchingRight[i])))
{
matchingLeft[v]=i;
matchingRight[i]=v;
return true;
}
return false;
}
Ответы (1 шт):
Описание, похоже, верное.
В коде неясно, что за N в цикле - здесь же должно быть количество ребер из вершины, т.е. свойство v, а не всего графа.
Сравните с e-maxx - может, какие тонкости ещё есть.