Построение компонент рёберной двусвязности — различия между версиями
Niko (обсуждение | вклад) (→Двупроходный алгоритм) |
Niko (обсуждение | вклад) |
||
Строка 44: | Строка 44: | ||
Можно найти компоненты реберной двусвязности за один проход, используя стек. | Можно найти компоненты реберной двусвязности за один проход, используя стек. | ||
− | + | Рекурсивый алгоритм на основе обхода в глубину. | |
− | Если мы возвращаясь обратно оказались в вершине, которая является вершиной моста, то все вершины, находящиеся, до текущей в стеке, принадлежат этой компоненте. Это следует из того, что [[Граф компонент реберной двусвязности | граф блоков и мостов, является деревом]]. По свойству обхода в | + | Если мы посетили вершину, то добавляем её в стек. Теперь определим, когда надо окрасить компоненту. |
+ | Если мы возвращаясь (в рекурсии) обратно оказались в вершине, которая является вершиной моста, то все вершины, находящиеся, до текущей в стеке, принадлежат этой компоненте. Это следует из того, что [[Граф компонент реберной двусвязности | граф блоков и мостов, является деревом]]. По свойству обхода в глубину, мы окажемся в висячей вершине, покрасим её, то есть эту компоненту покрасим. Её можно выкинут и рассматривать оставшийся граф. Действуя по аналогии мы всегда выкидываем компоненту реберной двусвязности следовательно, если мы вернулись в вершину, которая была концом нашего моста, то все вершины лежащие до нашей в стеке, принадлежат данной компоненте, либо если моста нет, то окрашиваемся всё, что лежит в стеке. | ||
Псевдокод: | Псевдокод: | ||
'''void paint(int v): | '''void paint(int v): | ||
− | maxcolor++ | + | maxcolor++ |
while (пока вершина стека не вершина <tex>v</tex> и стек не пустой) | while (пока вершина стека не вершина <tex>v</tex> и стек не пустой) | ||
− | извлекаем вершину стека и красим её | + | извлекаем вершину стека и красим её |
Строка 57: | Строка 58: | ||
'''void dfs(вершина v, предок вершины p): | '''void dfs(вершина v, предок вершины p): | ||
добавляем вершину в в стек; | добавляем вершину в в стек; | ||
− | state[v] = 1 | + | state[v] = 1 |
− | ret[v] = enter[v] = ++time | + | ret[v] = enter[v] = ++time |
для всех вершин u смежных v: | для всех вершин u смежных v: | ||
если (u == parent): | если (u == parent): | ||
переходим к следующей итерации | переходим к следующей итерации | ||
если (state[u] = 1): | если (state[u] = 1): | ||
− | ret[v] = min(ret[v], enter[u]) | + | ret[v] = min(ret[v], enter[u]) |
иначе: | иначе: | ||
если (state[u] = 0): | если (state[u] = 0): | ||
− | dfs(u, v) | + | dfs(u, v) |
− | ret[v] = min(ret[v], ret[u]) | + | ret[v] = min(ret[v], ret[u]) |
если (enter[v] < ret[u]): | если (enter[v] < ret[u]): | ||
− | paint(u) | + | paint(u) |
− | state[v] = 2 | + | state[v] = 2 |
Строка 78: | Строка 79: | ||
Итоговое время работы алгоритма <tex> O(|V| + |E|)</tex>. | Итоговое время работы алгоритма <tex> O(|V| + |E|)</tex>. | ||
− | == | + | == Визуализатор == |
− | |||
− | |||
− | |||
− | |||
* [http://rain.ifmo.ru/cat/view.php/vis/graph-general/bridges-2001| Визуализация построение компонент реберной двусзяности] | * [http://rain.ifmo.ru/cat/view.php/vis/graph-general/bridges-2001| Визуализация построение компонент реберной двусзяности] | ||
Версия 08:33, 22 ноября 2011
Содержание
Основные понятия
Построение компонент реберной двусвязности будет осуществляться с помощью обхода в глубину.
Двупроходный алгоритм
Первый способ найти искомые компоненты - сначала определить критерий перехода в новую компоненту реберной двусвязности, а затем покрасить вершины графа в нужные цвета.
Первый проход определяет для каждой вершины ret(v)
две величины: - время входа поиска в глубину в вершину иОпределим критерий перехода к новой компоненте. Воспользуемся ранее доказанной леммой.
Основываясь на этом, определим алгоритм окраски вершин графа. Перешли по мосту, следовательно началась новая компонента.
Псевдокод второго прохода:
void paint(v, цвет): colors(v) := цвет для всех вершин u, смежных v: если colors(u) равен нулю (вершина не покрашена): если ret(u) = enter(u): увеличиваем максимальный цвет paint(u, максимальный цвет) иначе: paint(u, цвет) ... обнуляем массив colors максимальный цвет := 0 для всех вершин v графа: если colors(v) = 0: увеличиваем максимальный цвет paint(v, максимальный цвет)
Вершины каждой из компонент реберной двусвязности окажутся окрашенными в свой цвет.
Время работы алгоритма будет время работы двух запусков dfs, то есть 2 *
, что есть .Однопроходный алгоритм
Можно найти компоненты реберной двусвязности за один проход, используя стек.
Рекурсивый алгоритм на основе обхода в глубину. Если мы посетили вершину, то добавляем её в стек. Теперь определим, когда надо окрасить компоненту. Если мы возвращаясь (в рекурсии) обратно оказались в вершине, которая является вершиной моста, то все вершины, находящиеся, до текущей в стеке, принадлежат этой компоненте. Это следует из того, что граф блоков и мостов, является деревом. По свойству обхода в глубину, мы окажемся в висячей вершине, покрасим её, то есть эту компоненту покрасим. Её можно выкинут и рассматривать оставшийся граф. Действуя по аналогии мы всегда выкидываем компоненту реберной двусвязности следовательно, если мы вернулись в вершину, которая была концом нашего моста, то все вершины лежащие до нашей в стеке, принадлежат данной компоненте, либо если моста нет, то окрашиваемся всё, что лежит в стеке. Псевдокод:
void paint(int v):
maxcolor++
while (пока вершина стека не вершина
и стек не пустой)
извлекаем вершину стека и красим её
void dfs(вершина v, предок вершины p): добавляем вершину в в стек; state[v] = 1 ret[v] = enter[v] = ++time для всех вершин u смежных v: если (u == parent): переходим к следующей итерации если (state[u] = 1): ret[v] = min(ret[v], enter[u]) иначе: если (state[u] = 0): dfs(u, v) ret[v] = min(ret[v], ret[u]) если (enter[v] < ret[u]): paint(u) state[v] = 2
Теперь две вершины имеют одинаковый цвет тогда и только тогда, когда они принадлежат одной компоненте реберной двусвязности.
Время работы dfs
. Покраска за . Итоговое время работы алгоритма .Визуализатор
Литература
Седжвик Роберт. Фундаментальные алгоритмы на C++. Часть 5: Алгоритмы на графах: Пер. с англ./Роберт Седжвик. — СПб.: ООО «ДиаСофтЮП», 2002. — С. 123-128
В.А.Кузнецов, А.М.Караваев. "Оптимизация на графах" - Петрозаводск, Издательство ПетрГУ 2007