Использование обхода в глубину для поиска точек сочленения
Версия от 06:42, 1 декабря 2010; 192.168.0.2 (обсуждение)
Содержание
Задача
Дан связный неориентированный граф. Требуется найти все точки сочленения в нем.
Алгоритм
Запустим обход в глубину из произвольной вершины графа . Рассмотрим :
- . Тогда, если найдётся такой потомок вершины в дереве поиска, что ни из него, ни из какого-либо его потомка нет ребра в предка вершины , то вершина будет являться точкой сочленения. В противном случае, вершина не является точкой сочленения.
- . - точка сочленения имеет хотя бы двух сыновей в дереве поиска в глубину.
Пусть
- время входа поиска в глубину в вершину . Через обозначим минимум из времени захода в саму вершину , времен захода в каждую из вершин , являющуюся концом некоторого обратного ребра , а также из всех значений для каждой вершины , являющейся непосредственным сыном в дереве поиска.Тогда, из вершины
или её потомка есть обратное ребро в её предка такой сын , что .Таким образом, если для текущей вершины
непосредственный сын : , то вершина является точкой сочленения; в противном случае она точкой сочленения не является.Реализация
В массиве
для каждой вершины содержится булево значение - является она точкой сочленения или нет. Изначально все значения false.dfstrue //задание времени входа в вершину u //задание начального значения up для вершины u //счетчик количества детей вершины u в дереве обхода for if continue if //v - предок вершины u, uv - обратное ребро else //v - ребенок вершины u dfs if true //не существует обратного ребра из вершины v или ее потомка в предка вершины u. вершина u - точка сочленения if //является ли u корнем дерева обхода ; //проверка количества детей у корня дерева