"Информатика (базовый и углублённый уровень)", Гейн А.Г., Сенокосов А.И.
Мосты и точки сочленения показывают уязвимые места связного графа. Мост — ребро, удаление которого разделяет граф на большее число компонент, а точка сочленения — вершина с таким же свойством. Для их поиска используют обход в глубину: он строит дерево посещения, записывает время входа и вычисляет low — возможность из поддерева добраться до предка. Эти идеи применяются при анализе надёжности сетей.
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Связный граф — граф, в котором между каждой парой вершин существует путь. Значит, из любой вершины можно добраться до любой другой, переходя по рёбрам. Это свойство нужно, чтобы осмысленно искать места, разрыв которых разделит всю сеть.
Мост — ребро, удаление которого увеличивает число компонент связности графа. Если связный граф был одной компонентой, после удаления моста появляются как минимум две. Понятие помогает находить единственные соединения между частями системы.
Точка сочленения — вершина, удаление которой вместе со всеми инцидентными рёбрами увеличивает число компонент связности. Такая вершина служит связующим узлом для нескольких частей графа. Её поиск показывает, какие узлы особенно опасны для надёжности сети.
Обход в глубину (DFS) последовательно углубляется в ещё не посещённые вершины. Время входа tin фиксирует момент первого посещения, а low показывает, до какого предка можно добраться из поддерева без возврата по родительскому ребру. Эти две величины позволяют искать мосты и точки сочленения без перебора вариантов удаления.
Если удалить мост связного графа, единственный путь между двумя его сторонами исчезает, поэтому вершины разделяются на разные компоненты. Ребро, лежащее в цикле, мостом не является: после его удаления можно обойти цикл в другую сторону. Следовательно, причина уязвимости ребра — отсутствие альтернативного пути, а не сам факт его принадлежности дереву обхода.
DFS начинает работу с выбранной вершины и идёт в ещё не посещённого соседа, пока это возможно. Рёбра, по которым алгоритм впервые попадает в вершины, образуют дерево обхода, а время входа задаёт порядок их посещения. Рёбра к уже посещённым предкам или другим вершинам помогают обнаружить дополнительные связи, которых нет в этом дереве.
Для вершины v значение low[v] равно минимальному времени входа в вершину, достижимую из её поддерева по рёбрам дерева и одному обратному ребру. При встрече обратного ребра к предку low уменьшается до времени входа этого предка. Ребро к родителю в обычном неориентированном графе не учитывают, потому что оно лишь отменяет шаг, которым алгоритм пришёл в вершину.
Пусть (u, v) — ребро дерева, где u — родитель, а v — потомок. Если из поддерева v нельзя попасть в u или выше, то после удаления (u, v) это поддерево оторвётся, поэтому ребро является мостом. В терминах значений это условие записывается так: low[v] > tin[u]. Равенство не подходит, поскольку путь к самому u уже сохраняет связность.
Для некорневой вершины u достаточно найти ребёнка v, для которого low[v] ≥ tin[u]: поддерево v не может подняться к предкам u и отделится после удаления u. У корня нет предка, поэтому сравнение с его временем входа неприменимо. Корень является точкой сочленения только при наличии более одного ребёнка в дереве обхода.
Сначала определите, является ли рассматриваемое ребро ребром дерева DFS, и найдите значения tin и low. Затем применяйте разные знаки неравенства для моста и точки сочленения. Отдельно проверяйте корень дерева обхода.
| Объект | Критерий | Что проверяется | Исключение или уточнение |
|---|---|---|---|
| Мост — ребро дерева обхода | low потомка > времени входа в родителя | Есть ли из поддерева путь в обход родительского ребра к предку | Обратное ребро к самому родителю не считается таким путём |
| Точка сочленения — некорневая вершина | low потомка ≥ времени входа в вершину | Может ли поддерево потомка связаться с предком вершины | Достаточно хотя бы одного такого потомка |
| Корень дерева обхода | У корня больше одного ребёнка в дереве обхода | Разделятся ли части графа после удаления корня | Критерий для некорневой вершины к корню не применяется |
В таблице потомком называется вершина, в которую DFS впервые пришёл из данной вершины. Сравнение нужно выполнять после обработки всего поддерева потомка, когда его значение low уже вычислено.
Условие: дан граф 1—2—3—4. Найдём все мосты и точки сочленения непосредственно по определениям. В цепи нет циклов, поэтому для каждого соединения нужно проверить, остаётся ли обходной путь.
Ответ: мосты — 1—2, 2—3 и 3—4; точки сочленения — 2 и 3. Здесь каждый мост очевиден, потому что ни одно ребро не входит в цикл.
Условие: рассмотрим цикл 1—2—3—1 и ответвление 3—4. Выполним DFS из вершины 1, выбирая соседей по порядку, и найдём мосты по значениям tin и low. Такой пример показывает, почему цикл защищает одни рёбра, но не защищает ответвление.
Ответ: единственный мост — 3—4. Точкой сочленения является вершина 3, поскольку после её удаления вершина 4 отделяется от цикла.
Условие: разработайте алгоритм, который получает список смежности неориентированного графа и выводит все мосты и точки сочленения. Граф может быть несвязным, поэтому одной стартовой вершины недостаточно. Для каждой вершины будем хранить родителя, tin, low и признак посещения.
Ответ: алгоритм находит все объекты за линейное время O(V + E), если список смежности хранится без повторного перебора рёбер. В графе с кратными рёбрами нужно передавать и проверять идентификатор ребра, а не только вершину-родителя.
Ошибка: считать мостом любое ребро дерева обхода. Её допускают, потому что дерево само по себе не содержит циклов, но исходный граф может иметь обратные рёбра. Проверяйте значение low: мостом будет только ребро с low[потомка] > tin[родителя].
Ошибка: использовать для моста условие low ≥ tin. При равенстве поддерево может вернуться к самому родителю по другому ребру, поэтому удаление не разрывает граф. Для самопроверки подставьте равенство в пример с циклом.
Ошибка: применять критерий некорневой вершины к корню. У корня нет предка, поэтому сравнение его времени входа с low ребёнка не объясняет разделение графа. Считайте именно число детей корня в дереве DFS.
Ошибка: считать ребро к родителю обычным обратным путём при наличии кратных рёбер. Два параллельных ребра соединяют те же вершины, но являются разными рёбрами, и одно из них может сохранить связность. Поэтому в списке смежности различайте идентификаторы рёбер.
Для работы нужны графы, вершины, рёбра, пути, циклы и компоненты связности. Также полезно уметь представлять неориентированный граф списком смежности. Без этих понятий трудно понять, что именно меняется после удаления объекта.
Обход в глубину используется не только здесь, но и для поиска компонент и проверки связности. Значения tin и low расширяют обычный DFS анализом структуры дерева обхода. Поэтому тема связывает базовые алгоритмы графов с более сложными методами.
Мосты и точки сочленения применяются при оценке надёжности компьютерных сетей и других систем связей. Они показывают каналы и узлы, отказ которых способен разделить систему. Найдя такие элементы, можно заранее добавить резервные соединения.
Может ли ребро, не входящее в дерево обхода в глубину, быть мостом?
Нет. Такое ребро является обратным и соединяет уже связанные части дерева обхода, поэтому его удаление обычно не нарушает связность. Если оно лежит в цикле, между его концами остаётся другой путь.
Почему при проверке мостов используется строгое неравенство?
Условие имеет вид low[v] > tin[u]. Если low[v] = tin[u], поддерево вершины v может вернуться к самому родителю u по другому ребру, поэтому удаление ребра (u, v) связность не нарушает.
Чем условие для корня дерева обхода отличается от условия для остальных вершин?
У корня нет предка, с которым можно сравнивать low. Поэтому корень является точкой сочленения тогда и только тогда, когда в дереве обхода у него больше одного ребёнка.
Зачем при вычислении low нужно учитывать обратные рёбра?
Обратное ребро показывает, может ли поддерево добраться до предка, минуя родительское ребро. Без него алгоритм принял бы некоторые рёбра и вершины за уязвимые, хотя в графе есть обходной путь.
Как правильно обрабатывать граф с несколькими компонентами связности?
Нужно запустить DFS из каждой ещё не посещённой вершины. Для каждой компоненты время входа и значения low можно считать в общей нумерации или начать заново, а найденные мосты и точки сочленения объединить.
Лабораторная работа № 25 (к § 54) Мосты и точки сочленения