Использование обхода в глубину для поиска мостов — различия между версиями
Niko (обсуждение | вклад) (→Лемма) |
м (rollbackEdits.php mass rollback) |
||
(не показано 20 промежуточных версий 9 участников) | |||
Строка 1: | Строка 1: | ||
− | |||
Дан неориентированный [[Основные определения теории графов#Граф| граф]] <tex> G </tex>. Найти все [[Мост, эквивалентные определения | мосты]] в <tex> G </tex> за время <tex> O(|V| + |E|)</tex> | Дан неориентированный [[Основные определения теории графов#Граф| граф]] <tex> G </tex>. Найти все [[Мост, эквивалентные определения | мосты]] в <tex> G </tex> за время <tex> O(|V| + |E|)</tex> | ||
Строка 5: | Строка 4: | ||
{{Теорема | {{Теорема | ||
|statement= | |statement= | ||
− | Пусть <tex> T </tex> | + | Пусть <tex> T </tex> — дерево [[Обход в глубину, цвета вершин | обхода в глубину графа]] <tex> G</tex>. Ребро <tex> (u, v) </tex> является мостом тогда и только тогда, когда <tex> (u, v) \in T</tex> и из вершины <tex> v</tex> и любого ее потомка нет обратного ребра в вершину <tex> u</tex> или предка <tex> u </tex> |
|proof= | |proof= | ||
<tex> \Leftarrow</tex> <br> | <tex> \Leftarrow</tex> <br> | ||
− | Удалим <tex> (u, v)</tex> из <tex> G</tex> Докажем, что мы не сможем достичь ни одного из предков <tex> v </tex> (в частности <tex> u </tex>). Пусть это не так, и <tex> w</tex> | + | Удалим <tex> (u, v)</tex> из <tex> G</tex>. Докажем, что мы не сможем достичь ни одного из предков <tex> v </tex> (в частности <tex> u </tex>). Докажем этот факт от противного. |
+ | Пусть это не так, и <tex> w</tex> — предпоследняя вершина на пути от <tex> v</tex> до ее предка <tex>x </tex>. Очевидно, <tex> (w, x)</tex> не ребро дерева (в силу единственности пути в дереве). Если <tex> (w, x)</tex> — обратное ребро, то это противоречит условию теоремы, так как <tex> x</tex> — предок <tex> u</tex>. Следовательно мы не достигнем предков <tex>v</tex>, а значит количество компонент связности увеличилось, поэтому ребро <tex>(u, v)</tex> является мостом.<br> | ||
<tex> \Rightarrow</tex> <br> | <tex> \Rightarrow</tex> <br> | ||
Пусть существует удовлетворяющее условию обратное ребро <tex>(x, w)</tex>. Тогда <tex>(u, v)</tex> лежит на цикле <tex>x \rightsquigarrow v \rightarrow u \rightsquigarrow w \rightarrow x</tex> и не может быть мостом. | Пусть существует удовлетворяющее условию обратное ребро <tex>(x, w)</tex>. Тогда <tex>(u, v)</tex> лежит на цикле <tex>x \rightsquigarrow v \rightarrow u \rightsquigarrow w \rightarrow x</tex> и не может быть мостом. | ||
Строка 16: | Строка 16: | ||
* <tex>enter(v)</tex> [[Использование обхода в глубину для топологической сортировки | время входа в вершину <tex>v </tex> ]] <br> | * <tex>enter(v)</tex> [[Использование обхода в глубину для топологической сортировки | время входа в вершину <tex>v </tex> ]] <br> | ||
− | * <tex>enter(x)</tex>, где <tex>x</tex> | + | * <tex>enter(x)</tex>, где <tex>x</tex> — потомок <tex>v</tex> <br> |
− | * <tex>enter( | + | * <tex>enter(w)</tex>, где <tex>(w, x)</tex> — обратное ребро, а <tex>w</tex> — потомок <tex>v</tex> (в нестрогом смысле) <br> |
===Лемма=== | ===Лемма=== | ||
{{Лемма | {{Лемма | ||
|statement = Ребро <tex>(u, v)</tex> является мостом тогда и только тогда, когда <tex>(u, v)</tex> принадлежит дереву обхода в глубину и <tex>ret(v) > enter(u)</tex> | |statement = Ребро <tex>(u, v)</tex> является мостом тогда и только тогда, когда <tex>(u, v)</tex> принадлежит дереву обхода в глубину и <tex>ret(v) > enter(u)</tex> | ||
− | | proof = Рассмотрим вершину <tex>v</tex> или её потомка. Из | + | | proof = Рассмотрим вершину <tex>v</tex> или её потомка. Из нее есть обратное ребро в предка <tex>v</tex> тогда и только тогда, когда найдется такой сын <tex>t</tex>, что <tex>ret[t] \le enter[v]</tex>. Если <tex>ret[t] = enter[v]</tex>, то найдется обратное ребро, приходящее точно в <tex>v</tex>. Если же <tex>ret[t] < enter[v]</tex>, то это означает наличие обратного ребра в какого-либо предка вершины <tex>v</tex>. |
Таким образом, если для текущего ребра <tex>(v, t)</tex> (принадлежащего дереву поиска) выполняется <tex>ret[t] > enter[v]</tex>, то это ребро является мостом; в противном случае оно мостом не является. | Таким образом, если для текущего ребра <tex>(v, t)</tex> (принадлежащего дереву поиска) выполняется <tex>ret[t] > enter[v]</tex>, то это ребро является мостом; в противном случае оно мостом не является. | ||
Строка 30: | Строка 30: | ||
{{Утверждение | {{Утверждение | ||
|statement = | |statement = | ||
− | <tex>ret(v)</tex> = <tex>min(</tex> | + | <tex>ret(v)</tex> = <tex>\min(</tex> <tex>enter(v) </tex>, <tex>enter(p)</tex>, <tex>ret(u)</tex> |
− | + | <tex>) </tex>, где <br> <tex>(v, p)</tex> — обратное ребро, <br> <tex>(v, u)</tex> — ребро дерева | |
− | |||
− | |||
− | <tex>) </tex> | ||
|proof = | |proof = | ||
− | [[Файл: | + | [[Файл:Bridges_dfs.png|300px|thumb|right|В скобах у вершины <tex>u</tex> указаны <tex>enter[u]</tex> и <tex>ret[u]</tex>. Мостами будут красные ребра]] |
− | + | #<tex>enter(v) </tex> <br>По определению функции <tex>ret</tex> <br> | |
− | По определению функции <tex>ret</tex> <br> | + | #<tex>enter(p)</tex>, <tex>(v, p)</tex> — обратное ребро <br><tex>p</tex> достижима из <tex>v</tex> по одному обратному ребру, значит величина <tex>ret(v)</tex> не больше <tex>enter(p)</tex> <br> |
− | + | #<tex>ret(u)</tex>, <tex>u</tex> — потомок <tex>v</tex> <br>Так как вершина <tex>u</tex> — потомок <tex>v</tex>, то обратное ребро из ее поддерева является обратным ребром из поддерева <tex>v</tex> <br> | |
− | <tex>p</tex> достижима из <tex>v</tex> по одному обратному ребру, значит величина <tex>ret(v)</tex> не больше <tex>enter(p)</tex> <br> | ||
− | |||
− | Так как вершина <tex>u</tex> | ||
}} | }} | ||
=== Псевдокод === | === Псевдокод === | ||
− | ''' | + | '''function''' dfs(v): |
− | + | time = time + 1 | |
− | + | enter[v] = time | |
− | + | ret[v] = time | |
− | '''for''' всех | + | '''for''' всех u смежных с v |
− | ''if'' | + | '''if''' (v, u) — обратное ребро |
− | + | ret[v] = min(ret[v], enter[u]) | |
− | '''if''' вершина | + | '''if''' вершина u — белая |
− | + | dfs(u) | |
− | + | ret[v] = min(ret[v], ret[u]) | |
− | '''if''' | + | '''if''' ret[u] > enter[v] |
− | ребро | + | ребро (v, u) — мост |
− | == | + | ==См. также== |
− | *[[Обход в глубину, цвета вершин | + | *[[Обход в глубину, цвета вершин]] |
− | *[[ | + | *[[Лемма о белых путях]] |
− | + | ==Источники информации== | |
− | + | * [http://e-maxx.ru/algo/bridge_searching MAXimal :: algo :: Поиск мостов] | |
− | + | * [http://en.wikipedia.org/wiki/Bridge_(graph_theory) Wikipedia — Bridge] | |
− | + | * [http://rain.ifmo.ru/cat/view.php/vis/graph-general/biconnected-components-2005| Визуализация поиска мостов] | |
− | ==Источники== | + | * ''Седжвик Р.'' Фундаментальные алгоритмы на C++. Часть 5: Алгоритмы на графах. Пер. с англ. — СПб.: ООО «ДиаСофтЮП», 2002. — С. 123-128 |
− | |||
− | |||
− | |||
− | |||
− | Седжвик | ||
[[Категория: Алгоритмы и структуры данных]] | [[Категория: Алгоритмы и структуры данных]] | ||
[[Категория: Обход в глубину]] | [[Категория: Обход в глубину]] |
Текущая версия на 19:12, 4 сентября 2022
Дан неориентированный граф . Найти все мосты в за время
Содержание
Алгоритм
Теорема: |
Пусть обхода в глубину графа . Ребро является мостом тогда и только тогда, когда и из вершины и любого ее потомка нет обратного ребра в вершину или предка — дерево |
Доказательство: |
|
Функция
Определим функцию
- время входа в вершину
-
-
Лемма
Лемма: |
Ребро является мостом тогда и только тогда, когда принадлежит дереву обхода в глубину и |
Доказательство: |
Рассмотрим вершину Таким образом, если для текущего ребра или её потомка. Из нее есть обратное ребро в предка тогда и только тогда, когда найдется такой сын , что . Если , то найдется обратное ребро, приходящее точно в . Если же , то это означает наличие обратного ребра в какого-либо предка вершины . (принадлежащего дереву поиска) выполняется , то это ребро является мостом; в противном случае оно мостом не является. |
Утверждение: |
— обратное ребро, — ребро дерева |
|
Псевдокод
function dfs(v): time = time + 1 enter[v] = time ret[v] = time for всех u смежных с v if (v, u) — обратное ребро ret[v] = min(ret[v], enter[u]) if вершина u — белая dfs(u) ret[v] = min(ret[v], ret[u]) if ret[u] > enter[v] ребро (v, u) — мост
См. также
Источники информации
- MAXimal :: algo :: Поиск мостов
- Wikipedia — Bridge
- Визуализация поиска мостов
- Седжвик Р. Фундаментальные алгоритмы на C++. Часть 5: Алгоритмы на графах. Пер. с англ. — СПб.: ООО «ДиаСофтЮП», 2002. — С. 123-128