Использование обхода в глубину для поиска точек сочленения — различия между версиями
(→Алгоритм) |
|||
| Строка 7: | Строка 7: | ||
{{Теорема | {{Теорема | ||
|statement= | |statement= | ||
| − | Пусть <tex>T</tex> — дерево [[Обход в глубину, цвета вершин|обхода в глубину]], <tex>root</tex> — корень <tex>T</tex>. Вершина <tex>u \ne root</tex> — точка сочленения <tex>\Leftrightarrow \exists v \in T</tex> — сын <tex>u</tex> : из <tex>v</tex> или любого потомка вершины <tex>v</tex> нет обратного ребра в предка вершины <tex>u</tex>. <tex>root</tex> — точка сочленения <tex>\Leftrightarrow root</tex> имеет хотя бы двух сыновей в дереве поиска в глубину. | + | Пусть <tex>T</tex> — дерево [[Обход в глубину, цвета вершин|обхода в глубину]], <tex>root</tex> — корень <tex>T</tex>. |
| + | * Вершина <tex>u \ne root</tex> — точка сочленения <tex>\Leftrightarrow \exists v \in T</tex> — сын <tex>u</tex> : из <tex>v</tex> или любого потомка вершины <tex>v</tex> нет обратного ребра в предка вершины <tex>u</tex>. | ||
| + | * <tex>root</tex> — точка сочленения <tex>\Leftrightarrow root</tex> имеет хотя бы двух сыновей в дереве поиска в глубину. | ||
|proof= | |proof= | ||
[[Файл:Joint_point_1.png|48px |thumb| | Рисунок к <tex>\Leftarrow</tex>]] | [[Файл:Joint_point_1.png|48px |thumb| | Рисунок к <tex>\Leftarrow</tex>]] | ||
Версия 22:36, 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 :: Поиск точек сочленения
