Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
00464.docx
Скачиваний:
17
Добавлен:
13.11.2022
Размер:
1.65 Mб
Скачать

Глубинная нумерация

Ввиду важности этого метода опишем еще два варианта алгоритма поиска в глубину. Первый из них - рекурсивный, и, как обычно, рекурсия дает возможность представить алгоритм в наиболее компактной форме. Для того чтобы алгоритм выполнял какую-то полезную работу, будем нумеровать вершины в том порядке, в каком они встречаются при обходе. Номер, получаемый вершиной , обозначается через и называется ее глубинным номером. Вначале полагаем для всех . Это нулевое значение сохраняется до тех пор, пока вершина не становится открытой, в этот момент ей присваивается ее настоящий глубинный номер. Таким образом, нет необходимости в какой-либо специальной структуре для запоминания новых вершин - они отличаются от всех других нулевым значением . Переменная хранит текущий номер. Рекурсивная процедура DFSR обходит одну компоненту связности, а алгоритм 1 обходит весь граф и присваивает вершинам глубинные номера.

Алгоритм 1. Поиск в глубину с вычислением глубинных номеров - рекурсивный вариант

  1. for do

  2. for do

  3. if then

Procedure

  1. for do

  2. if then

Построение каркаса

Следующий вариант алгоритма поиска в глубину отличается тем, что не использует стека для хранения открытых вершин. Стек нужен для того, чтобы в момент, когда окрестность активной вершины исследована и необходимо сделать "шаг назад", можно было определить вершину, в которую нужно вернуться. Но это та вершина, которая является отцом вершины в DFS-дереве. Поэтому, если решение задачи предусматривает построение DFS-дерева, то это дерево можно использовать и для организации "возвратных движений" в процессе обхода. Описываемый ниже алгоритм строит каркас произвольного графа, каждая компонента связности этого каркаса является DFS-деревом соответствующей компоненты связности графа. Через обозначается отец вершины в этом DFS-дереве, при этом для корня дерева (стартовой вершины) полагаем . Здесь и далее в описаниях алгоритмов инструкция "открыть (закрыть) вершину" означает, что вершина каким-то образом помечается как открытая (закрытая).

Алгоритм 2. Поиск в глубину с построением каркаса

  1. пометить все вершины как новые

  2. for do

  3. if вершина новая then

Procedure

  1. открыть вершину

  2. while открытая do

  3. if имеется неисследованное ребро

  4. then исследовать ребро

  5. if вершина новая

  6. then

  7. открыть вершину

  8. else закрыть вершину

Шарниры

В качестве примера задачи, для эффективного решения которой можно использовать основное свойство DFS-дерева, выражаемое теоремой 1, рассмотрим задачу выявления шарниров в графе. Напомним, что шарниром называется вершина, при удалении которой увеличивается число компонент связности. Отсутствие поперечных ребер относительно DFS-дерева позволяет очень просто узнать, является ли стартовая вершина (корень этого дерева) шарниром.

Лемма 1. Стартовая вершина а является шарниром графа тогда и только тогда, когда ее степень в DFS-дереве больше .

Доказательство. Если вершину удалить из дерева, то оно распадется на поддеревья, называемые ветвями. Число ветвей равно степени вершины в дереве. Так как поперечных ребер нет, то вершины из разных ветвей не могут быть смежными в графе и каждый путь из одной ветви в другую обязательно проходит через вершину . Следовательно, если степень вершины в DFS-дереве больше 1, то эта вершина - шарнир. Если же степень вершины в DFS-дереве равна 1, то в дереве имеется единственная вершина , смежная с , и каждая из остальных вершин графа соединена с вершиной путем, не проходящим через . Поэтому в данном случае удаление вершины не нарушает связности графа и эта вершина не является шарниром.

Это свойство корня DFS-дерева можно было бы использовать для выявления всех шарниров, просто выполнив раз поиск в глубину, стартуя поочередно в каждой вершине. Оказывается, все шарниры можно выявить однократным поиском в глубину. Следующая теорема характеризует все шарниры, отличные от корня DFS-дерева. Напомним, что каждая вершина дерева является и предком, и потомком самой себя. Предок (потомок) вершины, отличный от самой этой вершины, называется собственным предком (потомком).

Теорема 2. Пусть - DFS-дерево графа с корнем . Вершина является шарниром графа тогда и только тогда, когда у нее в дереве имеется такой сын , что ни один потомок вершины не соединен ребром ни с одним собственным предком вершины .

Доказательство. Если - сын вершины и ни один потомок вершины не соединен ребром ни с одним собственным предком вершины , то, ввиду отсутствия поперечных ребер, любой путь, соединяющий вершину с корнем, проходит через . Следовательно, в этом случае вершина - шарнир. Если же для каждого сына вершины имеется ребро, соединяющее вершину с каким-либо собственным предком вершины , то каждый сын вершины соединен с корнем дерева путем, не проходящим через . Поэтому при удалении вершины граф останется связным и в этом случае не является шарниром.

Для применения этого критерия к поиску шарниров введем на множестве вершин функцию , связанную с DFS-деревом: значением является наименьший из глубинных номеров вершин, смежных с потомками вершины . Если вершина является сыном вершины , то (так как вершина является потомком самой себя и смежна с вершиной ). Из теоремы 2 следует, что вершина , отличная от , является шарниром тогда и только тогда, когда у нее имеется сын такой, что .

Функцию можно определить рекурсивно - если мы знаем ее значения для всех сыновей вершины и глубинные номера всех вершин, смежных с и не являющихся ее сыновьями, то есть минимум из всех этих величин, то есть

где обозначает множество всех сыновей вершины , а - множество всех остальных вершин, смежных с . Нетрудно видеть, что это определение эквивалентно первоначальному. Исходя из него, можно вычислять значения функции в процессе поиска в глубину с помощью следующей рекурсивной процедуры. Предполагается, что вначале всем элементам массива присвоены нулевые значения.

Procedure

  1. for do

  2. if

  3. then ComputeLow( )

  4. else

Лекция 3. Эйлеровы и гамильтоновы циклы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]