Использование обхода в глубину для поиска точек сочленения — различия между версиями
(→Псевдокод) |
|||
Строка 32: | Строка 32: | ||
<br clear="all"> | <br clear="all"> | ||
− | == Псевдокод == | + | === Псевдокод === |
'''function''' findCutPoints(G[n]: '''Graph'''):<font color=darkgreen> // функция принимает граф G с количеством вершин n и выполняет поиск точек сочленения во всем графе </font> | '''function''' findCutPoints(G[n]: '''Graph'''):<font color=darkgreen> // функция принимает граф G с количеством вершин n и выполняет поиск точек сочленения во всем графе </font> | ||
Строка 57: | Строка 57: | ||
'''if''' '''not''' visited[i] | '''if''' '''not''' visited[i] | ||
dfs(i, -1) | dfs(i, -1) | ||
+ | |||
== Время работы == | == Время работы == | ||
Оценим время работы алгоритма. Процедура <tex>\mathrm{dfs}</tex> вызывается от каждой вершины не более одного раза, а внутри процедуры рассматриваются все такие [[Основные определения теории графов|ребра]] <tex>\{e\ |\ \mathrm{begin(e)} = u\}</tex>. Всего таких ребер для всех вершин в графе <tex>O(E)</tex>, следовательно, время работы алгоритма оценивается как <tex>O(V+E)</tex>. Такое же, как у [[Обход в глубину, цвета вершин|обхода в глубину]]. | Оценим время работы алгоритма. Процедура <tex>\mathrm{dfs}</tex> вызывается от каждой вершины не более одного раза, а внутри процедуры рассматриваются все такие [[Основные определения теории графов|ребра]] <tex>\{e\ |\ \mathrm{begin(e)} = u\}</tex>. Всего таких ребер для всех вершин в графе <tex>O(E)</tex>, следовательно, время работы алгоритма оценивается как <tex>O(V+E)</tex>. Такое же, как у [[Обход в глубину, цвета вершин|обхода в глубину]]. |
Версия 23:45, 8 января 2017
Задача: |
Дан связный неориентированный граф . Найти все точки сочленения в за время |
Алгоритм
Теорема: |
Пусть обхода в глубину, — корень .
— дерево
|
Доказательство: |
|
Пусть
— время входа поиска в глубину в вершину . Через обозначим минимум из времени захода в саму вершину , времен захода в каждую из вершин , являющуюся концом некоторого обратного ребра , а также из всех значений для каждой вершины , являющейся непосредственным сыном в дереве поиска.Тогда из вершины
или её потомка есть обратное ребро в её предка такой сын , что .Таким образом, если для текущей вершины
существует непосредственный сын : , то вершина является точкой сочленения, в противном случае она точкой сочленения не является.
Псевдокод
function findCutPoints(G[n]: Graph): // функция принимает граф G с количеством вершин n и выполняет поиск точек сочленения во всем графе visited = array[n, false] function dfs(v: int, p: int): time = time + 1 up[v] = tin[v] = time visited[v] = true for u: (v, u) in G if u == p continue if visited[u] up[v] = min(up[v], tin[u]) else dfs(u, v) up[v] = min(up[v], tin[u]) if up[to] >= tin[v] && p != -1 // если граф состоит из 2 вершин и одного ребра, то p != -1 спасёт, иначе выведет 1 точку сочленения v — cutpoint if v is root v — cutpoint for i = 1 to n if not visited[i] dfs(i, -1)
Время работы
Оценим время работы алгоритма. Процедура ребра . Всего таких ребер для всех вершин в графе , следовательно, время работы алгоритма оценивается как . Такое же, как у обхода в глубину.
вызывается от каждой вершины не более одного раза, а внутри процедуры рассматриваются все такиеСм. также
Источники информации
- Асанов М., Баранский В., Расин В. — Дискретная математика: Графы, матроиды, алгоритмы — Лань, 2010. — 368 с. — ISBN 978-5-8114-1068-2
- MAXimal :: algo :: Поиск точек сочленения