Построение компонент рёберной двусвязности — различия между версиями
Novik (обсуждение | вклад) м (→Источники информации) |
Novik (обсуждение | вклад) (→Двупроходный алгоритм) |
||
| Строка 5: | Строка 5: | ||
Первый способ найти искомые компоненты {{---}} сначала определить критерий перехода в новую [[Отношение реберной двусвязности#Компоненты реберной двусвязности|компоненту реберной двусвязности]], а затем покрасить вершины графа в нужные цвета. | Первый способ найти искомые компоненты {{---}} сначала определить критерий перехода в новую [[Отношение реберной двусвязности#Компоненты реберной двусвязности|компоненту реберной двусвязности]], а затем покрасить вершины графа в нужные цвета. | ||
| − | + | Определим критерий перехода к новой компоненте. | |
| + | Воспользуемся ранее доказанной [[Использование обхода в глубину для поиска мостов#Лемма | леммой]]. Получается {{---}} перешли по мосту, следовательно началась новая компонента. | ||
| − | + | '''Первый проход:''' Ищем в графе мосты. | |
| − | |||
| − | + | '''Второй проход:''' Окрашиваем вершины. | |
| + | Первым проходом запустим [[Использование обхода в глубину для поиска мостов|алгоритм для поиска мостов]], чтобы посчитать две величины: <tex>tin(v)</tex> и <tex>up(v)</tex>. | ||
=== Псевдокод второго прохода === | === Псевдокод второго прохода === | ||
| − | + | '''function''' paint(<tex>v</tex>, color): | |
| − | + | colors[<tex>v</tex>] = color | |
| − | + | '''for''' <tex>(u, v) \in E</tex>: | |
| − | + | '''if''' colors[<tex>u</tex>] == 0: | |
| − | + | '''if''' up[<tex>u</tex>] > tin[<tex>v</tex>]: | |
| − | + | maxColor++ | |
| − | + | paint(<tex>u</tex>, maxColor) | |
| − | + | '''else''': | |
| − | + | paint(<tex>u</tex>, color) | |
| − | + | ||
| − | + | '''function''' solve(): | |
| − | + | '''for''' <tex>v \in V</tex> : | |
| − | + | colors[<tex>v</tex>] = 0 | |
| − | + | '''if''' '''not''' visited[<tex>v</tex>] | |
| − | + | dfs(<tex>v</tex>) | |
| − | + | maxColor = 0 | |
| − | + | '''for''' <tex>v \in V</tex> : | |
| + | '''if''' colors[<tex>v</tex>] == 0: | ||
| + | maxColor++ | ||
| + | paint(<tex>v</tex>, maxColor) | ||
Вершины каждой из компонент реберной двусвязности окажутся окрашенными в свой цвет. | Вершины каждой из компонент реберной двусвязности окажутся окрашенными в свой цвет. | ||
Версия 22:51, 10 ноября 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 (): maxColor++ while stack.top() != and not stack.empty() colors[stack.top()] maxColor stack.pop()
function () time time + stack.push() enter[] time ret[] time for : if — обратное ребро ret[] min(ret[], enter[]) if not visited[] () ret[] min(ret[], ret[]) if ret[] > enter[] ()
Теперь две вершины имеют одинаковый цвет тогда и только тогда, когда они принадлежат одной компоненте реберной двусвязности.
Время работы dfs . Покраска за . Итоговое время работы алгоритма .
Источники информации
- Седжвик Р. Фундаментальные алгоритмы на C++. Часть 5: Алгоритмы на графах. Пер. с англ. — СПб.: ООО «ДиаСофтЮП», 2002. — С. 123-128
- Кузнецов В.А., Караваев. А.М. "Оптимизация на графах" - Петрозаводск, Издательство ПетрГУ 2007
- Визуализация — Построение компонент реберной двусзяности