Использование обхода в глубину для поиска точек сочленения — различия между версиями
м |
(→Реализация) |
||
| Строка 29: | Строка 29: | ||
== Реализация == | == Реализация == | ||
| − | + | '''function''' findCutPoints(G[n]: '''Graph'''):<font color=darkgreen> // функция принимает граф G с количеством вершин n и выполняет поиск точек сочленения во всем графе </font> | |
| − | + | 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] == ''true'' | |
| − | dfs( | + | up[v] = min(up[v], tin[u]) |
| − | + | '''else''' | |
| − | if | + | dfs(u, v) |
| − | + | up[v] = min(up[v], tin[u]) | |
| − | + | '''if''' up[to] >= tin[v] && p != -1 <font color=darkgreen>//если граф состоит из 2 вершин и одного ребра, то p != -1 спасёт, иначе выведет 1 точку сочленения </font> | |
| − | + | v — cutpoint | |
| − | + | '''if''' v — root | |
| − | + | v — cutpoint | |
| − | + | ||
| − | + | '''for''' i = 1 '''to''' n | |
| − | + | '''if''' visited[i] == ''false'' | |
| − | + | dfs(i, -1) | |
| − | |||
| − | |||
| − | |||
== См. также == | == См. также == | ||
Версия 17:10, 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] == true
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 — root
v — cutpoint
for i = 1 to n
if visited[i] == false
dfs(i, -1)
См. также
Источники информации
- Асанов М., Баранский В., Расин В. — Дискретная математика: Графы, матроиды, алгоритмы — Лань, 2010. — 368 с. — ISBN 978-5-8114-1068-2
- MAXimal :: algo :: Поиск точек сочленения