Использование обхода в глубину для поиска компонент сильной связности — различия между версиями
(→Литература) |
(→Доказательство корректности алгоритма) |
||
Строка 20: | Строка 20: | ||
<tex>\Leftarrow</tex> | <tex>\Leftarrow</tex> | ||
− | + | # Вершины <tex>s</tex> и <tex>t</tex> лежат в одном и том же дереве поиска в глубину на третьем этапе алгоритма. Значит, что они обе достижимы из корня <tex>r</tex> этого дерева. | |
+ | # Вершина <tex>r</tex> была рассмотрена вторым обходом в глубину раньше, чем <tex>s</tex> и <tex>t</tex>, значит время выхода из нее при первом обходе в глубину больше, чем время выхода из вершин <tex>s</tex> и <tex>t</tex>. Из этого мы получаем 2 случая: | ||
+ | ##Обе эти вершины были достижимы из <tex>r</tex> в инвертированном графе. А это означает взаимную достижимость вершин <tex>s</tex> и <tex>r</tex> и взаимную достижимость вершин <tex>r</tex> и <tex>t</tex>. А складывая пути мы получаем взаимную достижимость вершин <tex>s</tex> и <tex>t</tex>. | ||
+ | ##Хотя бы одна не достижима из <tex>r</tex> в инвертированном графе, например <tex>t</tex>. Значит и <tex>r</tex> была не достижима из <tex>t</tex> в инвертированном графе, так как время выхода <tex>r</tex> - больше . Значит между этими вершинами нет пути, но последнего быть не может, потому что <tex>t</tex> была достижима из <tex>r</tex> по пункту 1). | ||
− | + | Значит, из случая 2.1 и не существования случая 2.2 получаем, что вершины <tex>s</tex> и <tex>t</tex> взаимно достижимы в обоих графах. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
Версия 15:04, 4 января 2016
Содержание
Алгоритм
Компоненты сильной связности в графе можно найти с помощью поиска в глубину в 3 этапа:
- Построить граф с обратными (инвертированными) рёбрами
- Выполнить в поиск в глубину и найти — время окончания обработки вершины
- Выполнить поиск в глубину в , перебирая вершины во внешнем цикле в порядке убывания
Полученные на 3-ем этапе деревья поиска в глубину будут являться компонентами сильной связности графа
Так как компоненты сильной связности и графа совпадают, то первый поиск в глубину для нахождения можно выполнить на графе , а второй — на .
Доказательство корректности алгоритма
Теорема: |
Вершины и взаимно достижимы после выполнения алгоритма они принадлежат одному дереву обхода в глубину. |
Доказательство: |
Если вершины и были взаимно достижимы в графе , то на третьем этапе будет найден путь из одной вершины в другую, это означает, что по окончанию алгоритма обе вершины лежат в одном поддереве.
|
Время работы алгоритма
- Для того, чтобы инвертировать все ребра в графе, представленном в виде списка потребуется действий. Для матричного представления графа не нужно выполнять никакие действия для его инвертирования.
- Количество ребер в инвертированном равно количеству ребер в изначальном графе, поэтому поиск в глубину будет работать за
- Поиск в глубину в исходном графе выполняется за .
В итоге получаем, что время работы алгоритма
.Псевдокод
Пусть
— исходный граф, —инвертированный граф. В массиве будем хранить номера вершин в порядке окончания обработки поиском в глубину в графе . В результате получаем массив , который каждой вершине сопоставляет номер её компоненты.function dfs1(v) color[v] = 1 for (всех i смежных с v) if (вершина i не посещена) dfs1(G[v][i]) Добавляем вершину v в конец списка ord function dfs2(v) component[v] = col for (всех i смежных с v) if (если вершина i еще не находится ни в какой компоненте) dfs2(H[v][i]) function main() считываем исходные данные, формируем массивы G и H for (по всем вершинам i графа G) if (вершина i не посещена) dfs1(i) col = 1 for (по всем вершинам i списка ord[] в обратном порядке) if (если вершина i не находится ни в какой компоненте) dfs2(i) col++
Источники информации
- Р.Седжвик. "Фундаментальные алгоритмы на С++. Алгоритмы на графах" - СПб, ДиаСофтЮП, 2002
- MAXimal :: algo :: Поиск компонент сильной связности, построение конденсации графа