Алгоритм Борувки — различия между версиями
Novik (обсуждение | вклад) м (→Пример) |
Novik (обсуждение | вклад) м (→Пример) |
||
Строка 52: | Строка 52: | ||
|-align="center" | |-align="center" | ||
|[[Файл:Boruvka_1.png|250px]] | |[[Файл:Boruvka_1.png|250px]] | ||
− | | <tex>{A}</tex><br/><tex>{B}</tex><br/><tex>{C}</tex><br/><tex>{D}</tex><br/><tex>{E}</tex><br/><tex>{F}</tex><br/><tex>{G}</tex> | + | | <tex>\{A\}</tex><br/><tex>\{B\}</tex><br/><tex>\{C\}</tex><br/><tex>\{D\}</tex><br/><tex>\{E\}</tex><br/><tex>\{F\}</tex><br/><tex>\{G\}</tex> |
|Начальный граф <tex>G</tex>. Каждая вершина является компонентой (синие окружности). | |Начальный граф <tex>G</tex>. Каждая вершина является компонентой (синие окружности). | ||
|-align="center" | |-align="center" | ||
|[[Файл:Boruvka_2.png|250px]] | |[[Файл:Boruvka_2.png|250px]] | ||
− | | <tex>{ABDF}</tex><br/><tex>{CEG}</tex> | + | | <tex>\{ABDF\}</tex><br/><tex>\{CEG\}</tex> |
|На первой итерации внешнего цикла для каждой компоненты были добавлены минимальные сопряженные ребра. Некоторые ребра добавлены несколько раз (<tex dpi = 120>AD</tex> и <tex dpi = 120>CE</tex>). Осталось две компоненты. | |На первой итерации внешнего цикла для каждой компоненты были добавлены минимальные сопряженные ребра. Некоторые ребра добавлены несколько раз (<tex dpi = 120>AD</tex> и <tex dpi = 120>CE</tex>). Осталось две компоненты. | ||
|-align="center" | |-align="center" | ||
|[[Файл:Boruvka_3.png|250px]] | |[[Файл:Boruvka_3.png|250px]] | ||
− | | <tex>{ABCDEFG}</tex> | + | | <tex>\{ABCDEFG\}</tex> |
|На последней итерации внешнего цикла было добавлено минимальное ребро, соединяющее две оставшиеся компоненты (ребро <tex dpi = 120>BE</tex>). Осталась одна компонента. Минимальное остовное дерево графа <tex dpi = 120>G</tex> построено. | |На последней итерации внешнего цикла было добавлено минимальное ребро, соединяющее две оставшиеся компоненты (ребро <tex dpi = 120>BE</tex>). Осталась одна компонента. Минимальное остовное дерево графа <tex dpi = 120>G</tex> построено. | ||
|- | |- |
Версия 19:45, 11 октября 2015
Алгоритм Борувки (англ. Borůvka's algorithm) — алгоритм поиска минимального остовного дерева во взвешенном неориентированном связном графе. Впервые был опубликован в 1926 году Отакаром Борувкой.
Содержание
Описание алгоритма
- Изначально каждая вершина графа — тривиальное дерево, а ребра не принадлежат никакому дереву.
- Для каждого дерева найдем минимальное инцидентное ему ребро. Добавим все такие ребра.
- Повторяем шаг пока в графе не останется только одно дерево .
Данный алгоритм может работать неправильно, если в графе есть ребра равные по весу. Например, полный граф из трех вершин, вес каждого ребра равен один. В могут быть добавлены все три ребра. Избежать эту проблему можно, например, выбирая в первом пункте среди ребер, равных по весу, ребро с наименьшим номером.
Доказательство корректности
Теорема: |
Алгоритм Борувки строит MST |
Доказательство: |
Очевидно, что в результате работы алгоритма получается дерево. Пусть — минимальное остовное дерево графа , а — дерево полученное после работы алгоритма.Покажем, что .Предположим обратное Понятно, что в момент, когда ребро . Пусть ребро — первое окрашенное ребро дерева , не принадлежащее дереву . Пусть — путь, соединяющий в дереве вершины ребра . красили, какое-то ребро (назовем его ) не было покрашено. По алгоритму . Однако тогда — остовное дерево веса не превышающего вес дерева . Получили противоречение. Следовательно . |
Реализация
У вершины есть поле
— компонента связности, которой принадлежит эта вершина.
//— исходный граф // — весовая функция function while for Component // Component — множество компонент связности в // для каждой компоненты связности вес минимального ребра = // разбиваем граф на компоненты связности обычным dfs-ом for if if if for Component // добавляем ребро если его не было в return |
Пример
Асимптотика
Внешний цикл повторяется
раз, так как количество компонент связности каждый раз уменьшается как минимум в двое(потому что в худшем случае будут объединятся пары компонент) и изначально равно количеству вершин. Что же касается внутреннего цикла, то он выполняется за , где — количество рёбер в исходном графе. Следовательно конечное время работы алгоритма .