Построение компонент рёберной двусвязности — различия между версиями
Novik (обсуждение | вклад) (→Однопроходный алгоритм) |
Novik (обсуждение | вклад) м |
||
Строка 71: | Строка 71: | ||
Время работы dfs <tex> O(|V| + |E|)</tex>. Покраска за <tex> O(|V|) </tex>. | Время работы dfs <tex> O(|V| + |E|)</tex>. Покраска за <tex> O(|V|) </tex>. | ||
Итоговое время работы алгоритма <tex> O(|V| + |E|)</tex>. | Итоговое время работы алгоритма <tex> O(|V| + |E|)</tex>. | ||
+ | |||
+ | == См. также == | ||
+ | * [[Построение компонент вершинной двусвязности]] | ||
+ | * [[Использование обхода в глубину для поиска мостов]] | ||
== Источники информации == | == Источники информации == |
Версия 16:57, 11 ноября 2015
Построение компонент реберной двусвязности будет осуществляться с помощью обхода в глубину.
Содержание
Двупроходный алгоритм
Первый способ найти искомые компоненты — сначала определить критерий перехода в новую компоненту реберной двусвязности, а затем покрасить вершины графа в нужные цвета.
Определим критерий перехода к новой компоненте. Воспользуемся ранее доказанной леммой. Получается — перешли по мосту, следовательно началась новая компонента.
Первый проход: Ищем в графе мосты.
Второй проход: Окрашиваем вершины. Первым проходом запустим алгоритм для поиска мостов, чтобы посчитать две величины: и .
Псевдокод второго прохода
function paint(, color): colors[ ] = color for : if colors[ ] == 0: if up[ ] > tin[ ]: maxColor++ paint( , maxColor) else: paint( , color)
function solve(): for: colors[ ] = 0 if not visited[ ] dfs( ) maxColor = 0 for : if colors[ ] == 0: maxColor++ paint( , maxColor)
Вершины каждой из компонент реберной двусвязности окажутся окрашенными в свой цвет.
Время работы алгоритма будет время работы двух запусков dfs, то есть
, что есть .Однопроходный алгоритм
Однопроходный алгоритм строится на базе алгоритма поиска мостов. Во-первых, создадим глобальный стек, и при спуске по дереву добавляем в него вершины. Во-вторых, когда возвращаемся назад, проверяем не является ли ребро мостом (при помощи леммы). Если это так, то то все вершины, находящиеся до текущего потомка в стеке, принадлежат одной компоненте.Заметим, что эта компонента будет висячей вершиной в дереве блоков и мостов, так как обходили граф поиском в глубину. Значит, ее можно выкинуть и продолжить поиск в оставшемся графе. Действуя по аналогии в получившемся графе, найдем оставшиеся компоненты реберной двусвязности.
Псевдокод
function paint(): maxColor++ while stack.top() != and not stack.empty() colors[stack.top()] = maxColor stack.pop()
function dfs() time = time + 1 stack.push( ) tin[ ] = time up[ ] = time for : if — обратное ребро up[ ] = min(up[ ], tin[ ]) if not visited[ ] dfs( ) up[ ] = min(up[ ], up[ ]) if up[ ] > tin[ ] paint( )
Теперь две вершины имеют одинаковый цвет тогда и только тогда, когда они принадлежат одной компоненте реберной двусвязности.
Время работы dfs
. Покраска за . Итоговое время работы алгоритма .См. также
Источники информации
- Седжвик Р. Фундаментальные алгоритмы на C++. Часть 5: Алгоритмы на графах. Пер. с англ. — СПб.: ООО «ДиаСофтЮП», 2002. — С. 123-128
- Кузнецов В.А., Караваев. А.М. "Оптимизация на графах" - Петрозаводск, Издательство ПетрГУ 2007
- Визуализация — Построение компонент реберной двусзяности