<?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=78.85.13.123&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=78.85.13.123&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/78.85.13.123"/>
		<updated>2026-05-24T19:03:48Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F_%D0%AD%D0%B9%D0%BB%D0%B5%D1%80%D0%BE%D0%B2%D0%B0_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B0&amp;diff=71902</id>
		<title>Деревья Эйлерова обхода</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F_%D0%AD%D0%B9%D0%BB%D0%B5%D1%80%D0%BE%D0%B2%D0%B0_%D0%BE%D0%B1%D1%85%D0%BE%D0%B4%D0%B0&amp;diff=71902"/>
				<updated>2019-10-26T07:27:02Z</updated>
		
		<summary type="html">&lt;p&gt;78.85.13.123: /* Декартово дерево по неявному ключу */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Задача о динамической связности==&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Для динамически изменяющегося дерева выполнить следующие запросы:&lt;br /&gt;
* '''&amp;lt;tex&amp;gt;\mathrm{link(u, w)}&amp;lt;/tex&amp;gt;''' {{---}} добавить ребро &amp;lt;tex&amp;gt;(u, w)&amp;lt;/tex&amp;gt; (при условии, что вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; принадлежат разным деревьям),&lt;br /&gt;
* '''&amp;lt;tex&amp;gt;\mathrm{cut(u, w)}&amp;lt;/tex&amp;gt;''' {{---}} разрезать ребро &amp;lt;tex&amp;gt;(u, w)&amp;lt;/tex&amp;gt; (при условии, что ребро &amp;lt;tex&amp;gt;(u, w)&amp;lt;/tex&amp;gt; принадлежит дереву),&lt;br /&gt;
* '''&amp;lt;tex&amp;gt;\mathrm{isConnected(u, w)}&amp;lt;/tex&amp;gt;''' {{---}} определить принадлежат ли вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; одной компоненте связности.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем представлять дерево в виде его [[Эйлеровость графов|эйлерова графа]], а затем будем работать с [[Эйлеровость графов|эйлеровым обходом]] (англ.''Euler tour tree'') этого графа. Это позволит выполнять указанные запросы за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Представление деревьев в виде эйлерова графа==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Tree.png|300px|thumb|left|Пример дерева]]&lt;br /&gt;
[[Файл:Euler graph.png|300px|thumb|right|Соответствующий эйлеров граф]]&lt;br /&gt;
&lt;br /&gt;
Для представления [[Дерево, эквивалентные определения|дерева]] в виде [[Эйлеровость графов|эйлерового графа]] заменим каждое ребро &amp;lt;tex&amp;gt;\{u, v\} \&amp;lt;/tex&amp;gt; дерева на два ребра &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(v, u)&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;
&amp;lt;br&amp;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;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Представим дерево в виде последовательности вершин, посещенных в порядке эйлерова обхода, начиная с вершины &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Tour1.png|thumb|320px|center]]&lt;br /&gt;
&lt;br /&gt;
==Операции c эйлеровыми обходами==&lt;br /&gt;
&lt;br /&gt;
===Добавление ребра===&lt;br /&gt;
&lt;br /&gt;
Для добавления ребра &amp;lt;tex&amp;gt;(c, g)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Выберем любое вхождение вершины &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; в эйлеров обход дерева &amp;lt;tex&amp;gt;T1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
*Разрежем эйлеров обход &amp;lt;tex&amp;gt;T1&amp;lt;/tex&amp;gt; на две части:&lt;br /&gt;
*: &amp;lt;tex&amp;gt;A1&amp;lt;/tex&amp;gt; {{---}} часть обхода до выбранного вхождения вершины &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, включая ее.&lt;br /&gt;
*: &amp;lt;tex&amp;gt;A2&amp;lt;/tex&amp;gt; {{---}} часть обхода после выбранного вхождения вершины &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, включая ее.&lt;br /&gt;
*Аналогично, выберем любое вхождение вершины &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; в эйлеров обход дерева &amp;lt;tex&amp;gt;T2&amp;lt;/tex&amp;gt; и разрежем его на две части &amp;lt;tex&amp;gt;B1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
*Соберем результирующий эйлеров обход в порядке &amp;lt;tex&amp;gt;A1, B2, B1&amp;lt;/tex&amp;gt; (без первой повторяющейся вершины), &amp;lt;tex&amp;gt;A2&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы быстро находить место, где разрезать эйлеровы обходы деревьев &amp;lt;tex&amp;gt;T1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T2&amp;lt;/tex&amp;gt;, будем хранить эйлеровы обходы в двоичных деревьях поиска. &lt;br /&gt;
Ключом вершины для построения дерева поиска будет время посещения этой вершины эйлеровым обходом.&lt;br /&gt;
Для каждой вершины дерева &amp;lt;tex&amp;gt;(T1, T2)&amp;lt;/tex&amp;gt; будем хранить указатель на вершину в дереве поиска, которая соответствует вхождению вершины дерева в эйлеров обход. &lt;br /&gt;
Тогда за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; переходим от вершины дерева к вершине дерева поиска, по которой за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt; можно будет разделить дерево поиска на две части.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Link22.png |thumb|400px|center|Рис.1a Исходный лес &amp;lt;br&amp;gt;Рис.1b Эйлеровы обходы деревьев&amp;lt;br&amp;gt; Рис.1с Двоичные деревья поиска для хранения эйлеровых обходов &amp;lt;br&amp;gt; Рис.1d Результирующий эйлеров обход]]&lt;br /&gt;
&lt;br /&gt;
===Разрезание ребра===&lt;br /&gt;
&lt;br /&gt;
Для удаления ребра &amp;lt;tex&amp;gt;(g, j)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
*Найдем в эйлеровом обходе дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; две пары посещений концов удаляемого ребра &amp;lt;tex&amp;gt;g,j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j,g&amp;lt;/tex&amp;gt;, которые соответствуют прохождениям по ребру &amp;lt;tex&amp;gt;(g, j)&amp;lt;/tex&amp;gt; в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.&lt;br /&gt;
*Разрежем эйлеров обход дерева по этим парам на три части: &amp;lt;tex&amp;gt;A1, A2, A3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
*Соединив &amp;lt;tex&amp;gt;A1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A3&amp;lt;/tex&amp;gt; (без повторяющейся первой вершины), получим эйлеров обход первого дерева, а &amp;lt;tex&amp;gt;A2&amp;lt;/tex&amp;gt; дает эйлеров обход второго дерева.&lt;br /&gt;
&lt;br /&gt;
Чтобы быстро находить места в эйлеровом обходе, которые соответствуют прохождению удаляемого ребра в дереве, будем для каждого ребра в дереве хранить ссылку на те места эйлерова обхода, где последовательно посещаем концы удаляемого ребра.&lt;br /&gt;
Так, для ребра &amp;lt;tex&amp;gt;(g, j)&amp;lt;/tex&amp;gt; храним ссылки на узлы дерева поиска, соответствующие парам посещений концов этого ребра.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Link23.png |thumb|400px|center|Рис.1a Исходное дерево &amp;lt;br&amp;gt;Рис.1b Эйлеров обход исходного дерева&amp;lt;br&amp;gt; Рис.1с Двоичное дерево поиска для хранения эйлерового обхода &amp;lt;br&amp;gt; Рис.1d Эйлеровы обходы получившихся деревьев]]&lt;br /&gt;
&lt;br /&gt;
===Проверка на связность===&lt;br /&gt;
Для того, чтобы проверить, лежат ли две вершины в одном дереве, достаточно подняться от вхождения каждой вершины в эйлеров обход (ссылку на которое мы храним) до корня дерева поиска, хранящего этот эйлеров обход.&lt;br /&gt;
&lt;br /&gt;
==Способы реализации структуры==&lt;br /&gt;
&lt;br /&gt;
===Сбалансированное дерево поиска===&lt;br /&gt;
&lt;br /&gt;
Будем хранить последовательность вершин эйлерова обхода в виде сбалансированного двоичного дерева поиска, например, в виде [[Красно-черное дерево|красно-черного дерева]]. При построении дерева ключом вершины будет время посещения этой вершины эйлеровым обходом. &lt;br /&gt;
&lt;br /&gt;
Операции объединения и разделения красно-черных деревьев выполняется за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.109.4875&amp;amp;rep=rep1&amp;amp;type=pdf Ron Wein {{---}} Efficient Implementation of Red-Black Trees.]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Декартово дерево по неявному ключу===&lt;br /&gt;
&lt;br /&gt;
Также, можем хранить последовательности вершин эйлерова обхода в [[Декартово_дерево_по_неявному_ключу|декартовом дереве по неявному ключу]]. Глубина декартового дерева, построенного на массиве из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, будет поддерживаться равной &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Операции объединения и разделения также выполняются за &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Link-Cut Tree]]&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Euler_tour_technique Wikipedia {{---}} Euler tour technique]&lt;br /&gt;
* [http://courses.csail.mit.edu/6.851/spring07/scribe/lec05.pdf Advanced Data Structures {{---}} Euler tour trees]&lt;br /&gt;
* [http://codeforces.com/blog/entry/18369?mobile=true&amp;amp;locale=en CodeForces {{---}} On Euler tour trees]&lt;br /&gt;
* [http://logic.pdmi.ras.ru/csclub/node/2819 Лекториум{{---}} Лекция Павла Маврина об эйлеровых обходах]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Обходы графов]]&lt;br /&gt;
[[Категория: Эйлеровы графы]]&lt;/div&gt;</summary>
		<author><name>78.85.13.123</name></author>	</entry>

	</feed>