<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.159.31&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.159.31&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.159.31"/>
		<updated>2026-04-13T02:51:55Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D1%80%D0%B0%D1%81%D0%BA%D0%B0%D0%BB%D0%B0&amp;diff=42203</id>
		<title>Алгоритм Краскала</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D1%80%D0%B0%D1%81%D0%BA%D0%B0%D0%BB%D0%B0&amp;diff=42203"/>
				<updated>2014-12-15T10:33:43Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.159.31: /* Задача о максимальном ребре минимального веса */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;b&amp;gt;Алгоритм Краскала&amp;lt;/b&amp;gt; (англ. ''Kruskal's algorithm'') — алгоритм поиска [[Лемма о безопасном ребре#Необходимые определения | минимального остовного дерева]] (англ. ''minimum spanning tree'', ''MST'') во взвешенном [[Основные определения теории графов#Неориентированные графы | неориентированном связном графе]].&lt;br /&gt;
&lt;br /&gt;
==Идея==&lt;br /&gt;
Будем последовательно строить подграф &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (&amp;quot;растущий лес&amp;quot;), пытаясь на каждом шаге достроить &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; до некоторого MST. Начнем с того, что включим в &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; все вершины графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;. Теперь будем обходить множество &amp;lt;tex&amp;gt;E(G)&amp;lt;/tex&amp;gt; в порядке неубывания веса ребер. Если очередное ребро &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; соединяет вершины одной компоненты связности &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, то добавление его в остов приведет к возникновению цикла в этой компоненте связности. В таком случае, очевидно, &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; не может быть включено в &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;. Иначе &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; соединяет разные компоненты связности &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, тогда существует &amp;lt;tex&amp;gt; \langle S, T \rangle &amp;lt;/tex&amp;gt; [[Лемма о безопасном ребре#Необходимые определения|разрез]] такой, что одна из компонент связности составляет одну его часть, а оставшаяся часть графа — вторую. Тогда &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; — минимальное ребро, пересекающее этот разрез. Значит, из [[Лемма о безопасном ребре#Лемма о безопасном ребре|леммы о безопасном ребре]] следует, что &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; является безопасным, поэтому добавим это ребро в &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;. На последнем шаге ребро соединит две оставшиеся компоненты связности, полученный подграф будет минимальным остовным деревом графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} исходный граф&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt; {{---}} минимальный остов&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;font color=green&amp;gt;// для проверки возможности добавления ребра используется система непересекающихся множеств&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''function''' &amp;lt;tex&amp;gt;\mathtt{kruskalFindMST}():&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt; \mathtt{F} \leftarrow V(G)&amp;lt;/tex&amp;gt;&lt;br /&gt;
    &amp;lt;tex&amp;gt;\mathtt{sort}(E(G))\&amp;lt;/tex&amp;gt;&lt;br /&gt;
    '''for''' &amp;lt;tex&amp;gt;vu \in E(G)&amp;lt;/tex&amp;gt;&lt;br /&gt;
       '''if''' &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; в разных компонентах связности &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;&lt;br /&gt;
          &amp;lt;tex&amp;gt; \mathtt{F}\ =\ \mathtt{F} \bigcup \mathtt{vu}\&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Задача о максимальном ребре минимального веса==&lt;br /&gt;
Очевидно, что максимальное ребро в MST минимально. Пусть это не так, тогда рассмотрим разрез, который оно пересекает. В этом разрезе должно быть ребро с меньшим весом, иначе максимальное ребро было бы минимальным, но в таком случае минимальный остов не является минимальным, следовательно, максимальное ребро в минимальном остовном дереве минимально. Если же максимальное ребро в остовном дереве минимально, то такое дерево может не быть минимальным. Зато его можно найти быстрее чем MST, а конкретно за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;. С помощью [[Поиск_k-ой_порядковой_статистики_за_линейное_время | алгоритма поиска k-ой порядковой статистики]] найдем ребро-медиану за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt; и разделим множество ребер на два равных по мощности так, чтобы в первом подмножестве все ребра не превосходили ребро-медиану, а во втором были не меньше его. Запустим [[Использование_обхода_в_глубину_для_проверки_связности|обход в глубину]], чтобы проверить образуют ли ребра из первого подмножества остов, содержащий все вершины графа. Если да, то, так как все ребра в первом подмножестве меньше чем во втором, рекурсивно запустим алгоритм от него. В противном случае сконденсируем в супервершины получившиеся несвязные компоненты и рассмотрим граф с этими супервершинами и ребрами из второго подмножества. На последнем шаге останется одно ребро, оно и будет максимальным ребром минимального веса. На каждом шаге ребер становится в два раза меньше, а все операции выполняются за время пропорциональное количеству ребер на текущем шаге, следовательно, время работы алгоритма &amp;lt;tex&amp;gt;O(E+\frac{E}{2}+\frac{E}{4}+...+1)=O(E)&amp;lt;/tex&amp;gt;. Чтобы восстановить остовное дерево, достаточно запустить алгоритм поиска в глубину и добавлять в остов только те ребра, которые не превосходят найденное алгоритмом ребро.&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
Задан неориентированный связный граф, требуется построить в нём минимальное остовное дерево.&amp;lt;br/&amp;gt;&lt;br /&gt;
Создадим новый граф, содержащий все вершины из заданного графа, но не содержащий рёбер.&amp;lt;br/&amp;gt;&lt;br /&gt;
Этот новый граф будет ответом, в него будут добавлены рёбра из заданного графа по ходу выполнения алгоритма.&amp;lt;br/&amp;gt;&lt;br /&gt;
Отсортируем рёбра заданного графа по их весам и рассмотрим их в порядке возрастания.&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Рёбра ''(в порядке их просмотра)'' || ae || cd || ab || be || bc || ec || ed&lt;br /&gt;
|-&lt;br /&gt;
| Веса рёбер ||&amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;6&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt; &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Изображение !! Описание&lt;br /&gt;
|-&lt;br /&gt;
|[[Файл:Mst_kruskal_1.png|200px]]&lt;br /&gt;
|style=&amp;quot;padding-left: 1em&amp;quot; |Первое ребро, которое будет рассмотрено — '''ae''', так как его вес минимальный.&amp;lt;br/&amp;gt;&lt;br /&gt;
Добавим его к ответу, так как его концы соединяют вершины из разных множеств ('''a''' — красное и '''e''' — зелёное).&amp;lt;br/&amp;gt;&lt;br /&gt;
Объединим красное и зелёное множество в одно (красное), так как теперь они соединены ребром.&lt;br /&gt;
|-&lt;br /&gt;
|[[Файл:Mst_kruskal_2.png|200px]]&lt;br /&gt;
|style=&amp;quot;padding-left: 1em&amp;quot; |Рассмотрим следующие ребро — '''cd'''.&amp;lt;br/&amp;gt;&lt;br /&gt;
Добавим его к ответу, так как его концы соединяют вершины из разных множеств ('''c''' — синее и '''d''' — голубое).&amp;lt;br/&amp;gt;&lt;br /&gt;
Объединим синее и голубое множество в одно (синее), так как теперь они соединены ребром.&lt;br /&gt;
|-&lt;br /&gt;
|[[Файл:Mst_kruskal_3.png|200px]]&lt;br /&gt;
|style=&amp;quot;padding-left: 1em&amp;quot; |Дальше рассмотрим ребро '''ab'''.&amp;lt;br/&amp;gt;&lt;br /&gt;
Добавим его к ответу, так как его концы соединяют вершины из разных множеств ('''a''' — красное и '''b''' — розовое).&amp;lt;br/&amp;gt;&lt;br /&gt;
Объединим красное и розовое множество в одно (красное), так как теперь они соединены ребром.&lt;br /&gt;
|-&lt;br /&gt;
|[[Файл:Mst_kruskal_4.png|200px]]&lt;br /&gt;
|style=&amp;quot;padding-left: 1em&amp;quot; |Рассмотрим следующие ребро — '''be'''.&amp;lt;br/&amp;gt;&lt;br /&gt;
Оно соединяет вершины из одного множества, поэтому перейдём к следующему ребру '''bc'''&amp;lt;br/&amp;gt;&lt;br /&gt;
Добавим его к ответу, так как его концы соединяют вершины из разных множеств ('''b''' — красное и '''c''' — синее).&amp;lt;br/&amp;gt;&lt;br /&gt;
Объединим красное и синее множество в одно (красное), так как теперь они соединены ребром.&lt;br /&gt;
|-&lt;br /&gt;
|[[Файл:Mst_kruskal_5.png|200px]]&lt;br /&gt;
|style=&amp;quot;padding-left: 1em&amp;quot; |Рёбра '''ec''' и '''ed''' соединяют  вершины из одного множества,&amp;lt;br/&amp;gt;&lt;br /&gt;
поэтому после их просмотра они не будут добавлены в ответ&amp;lt;br/&amp;gt;&lt;br /&gt;
Всё рёбра были рассмотрены, поэтому алгоритм завершает работу.&amp;lt;br/&amp;gt;&lt;br /&gt;
Полученный граф — минимальное остовное дерево&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Асимптотика==&lt;br /&gt;
Сортировка &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; займет &amp;lt;tex&amp;gt;O(E\log E)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Работа с [[СНМ (реализация с помощью леса корневых деревьев) | системой непересекающихся множеств]] займет &amp;lt;tex&amp;gt;O(E\alpha(V))&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; — обратная функция Аккермана, которая не превосходит 4 во всех практических приложениях и которую можно принять за константу.&amp;lt;br&amp;gt;&lt;br /&gt;
Алгоритм работает за &amp;lt;tex&amp;gt;O(E(\log E+\alpha(V))) = O(E\log E)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Алгоритм Прима]]&lt;br /&gt;
* [[Алгоритм Борувки]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн — Алгоритмы: построение и анализ, 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F_%D0%90%D0%BA%D0%BA%D0%B5%D1%80%D0%BC%D0%B0%D0%BD%D0%B0 Википедия — Функция Аккермана]&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9A%D1%80%D1%83%D1%81%D0%BA%D0%B0%D0%BB%D0%B0 Википедия — Алгоритм Крускала]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Kruskal's_algorithm Wikipedia — Kruskal's algorithm]&lt;br /&gt;
* [http://e-maxx.ru/algo/mst_kruskal MAXimal :: algo :: Минимальное остовное дерево. Алгоритм Крускала]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Остовные деревья ]]&lt;/div&gt;</summary>
		<author><name>217.66.159.31</name></author>	</entry>

	</feed>