Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

608 Глава 13. Алгоритмы графа

Этот простой процесс пересекает все края G. (См. рисунок 13.6.)

(a) (b)

(c) (d)

(e) (f)

Рисунок 13.6: Пример глубины сначала ищет пересечение на графе, начинающемся в вершине A. Края открытия показывают с твердыми линиями, и спинку показывают с пунктирными линиями: (a) входной граф; (b) путь краев открытия, прослеженных от, пока, спинка (B, A) не поражена; (c) достигающий F, который является тупиком; (d) после возвращения к C, resum-луг с краем (C, G), и удар другого тупика, J; (e) после возвращения к G; (f) после возвращения к N.

13.3. Пересечения графа 609

Края открытия и спинка

Мы можем визуализировать пересечение DFS, ориентируя края вдоль направления, в котором они исследуются во время пересечения, отличать края раньше обнаруживало новые вершины, названные краями открытия или краями дерева, от тех, которые уже приводят к посещенным вершинам, названным спинкой. (См. рисунок 13.6 (f).) На аналогии выше, края открытия - края, где мы разворачиваем нашу последовательность, когда мы пересекаем их, и спинка - края, куда мы немедленно возвращаемся, не разворачивая последовательности. Как мы будем видеть, края открытия формируют дерево охвата связанного компонента стартовой вершины s. Мы называем края не в этом дереве «спинкой», потому что, предполагая, что дерево внедрено в вершине начала, каждый такой край возвращается от вершины в этом дереве одному из его предков в дереве.

Псевдокодекс для пересечения DFS, начинающегося в вершине v, следует за нашей аналогией с последовательностью и краской. Мы используем рекурсию, чтобы осуществить аналогию последовательности, и мы предполагаем, что у нас есть механизм (аналогия краски), чтобы определить, были ли вершина или край исследованы или нет, и маркировать края как края открытия или спинку. Этот механизм потребует дополнительного пространства и может затронуть продолжительность алгоритма. Псевдокодовое описание рекурсивного алгоритма DFS дано в Кодовом Фрагменте 13.1.

Алгоритм DFS (G, v):

Вход: граф G и вершина v Продукции G: маркировка краев в связанном компоненте v как открытие

края и спинка маркируют v, как посещается для всех краев e в v.incidentEdges (), делают

если край e не посещают тогда

w¬ e.opposite (v)

если вершина w неизведанна тогда

маркируйте e как край открытия, рекурсивно называют DFS (G, w)

еще

маркируйте e как спинку

Кодовый Фрагмент 13.1: алгоритм DFS.

Есть много наблюдений, что мы можем сделать о глубине, сначала ищут алгоритм, многие из которых происходят из способа, которым алгоритм DFS делит края ненаправленного графа G в две группы, края открытия и спинку. Например, так как спинка всегда соединяет вершину v с пред - viously посещаемая вершина u, каждая спинка подразумевает цикл в G, состоя из краев открытия от u до v плюс спинка (u, v).

610

Глава 13. Суждение Алгоритмов графа 13.12: Позвольте G быть ненаправленным графом, на котором пересекающееся начало DFS - был выполнен луг в вершине s. Тогда пересечение посещает все вершины в связанном компоненте s, и края открытия формируют дерево охвата связанного компонента s.

Оправдание: Предположим, что есть по крайней мере одна вершина v в связанном компоненте s, который не посещают, и позвольте w быть первой непосещаемой вершиной на некотором пути от s до v (у нас может быть v = w). Так как w - первая непосещаемая вершина на этом пути, у этого есть соседний u, который посетили. Но когда мы посетили u, мы, должно быть, рассмотрели край (u, w); следовательно, это не может быть правильно, что w не посещают. Поэтому, в связанном компоненте s нет никаких непосещаемых вершин.

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

С точки зрения ее продолжительности глубина первый поиск - эффективный метод для travers-

луг граф. Обратите внимание на то, что DFS называют точно однажды на каждой вершине, и что каждый край исследован точно дважды, однажды от каждой из его вершин конца. Таким образом, если не уточнено вершины и ms края находятся в связанном компоненте вершины s, DFS, начинающийся при пробегах s в O (не уточнено + ms) время, если следующие условия удовлетворены:

• Граф представлен структурой данных, таким образом что создание и iterat-

луг через список, произведенный v.incidentEdges (), берет O (степень (v)) время,

и e.opposite (v) берет O (1) время. Структура списка смежности - одна такая структура, но структура матрицы смежности не.

• У нас есть способ «отметить» вершину или край, как исследуется, и проверить если вершина

или край был исследован в O (1) время. Мы обсуждаем способы осуществить

DFS, чтобы достигнуть этой цели в следующей секции.

Учитывая предположения выше, мы можем решить много интересных проблем.

Суждение 13.13: Позвольте G быть графом с n вершинами и m краями, представленными со списком смежности. Пересечение DFS G может быть выполнено в O (n + m) время и может использоваться, чтобы решить следующие проблемы в O (n + m) время:

Тестирование, связан ли G

Вычисление дерева охвата G, если G связан вычисление связанных компонентов G вычисление пути между двумя данными вершинами G, если это существует вычисление цикла в G, или сообщая, что у G нет циклов

Оправдание Суждения 13.13 основано на алгоритмах, которые используют немного измененные версии алгоритма DFS как подпрограммы.