Деревья Эйлерова обхода — различия между версиями
(→Реализация структуры) |
Sokolova (обсуждение | вклад) (→Операции c эйлеровыми обходами) |
||
Строка 37: | Строка 37: | ||
==Операции c эйлеровыми обходами== | ==Операции c эйлеровыми обходами== | ||
Представление деревьев в виде их эйлеровых обходов позволяет свести задачу о динамической связности к следующим операциям с последовательностями вершин: | Представление деревьев в виде их эйлеровых обходов позволяет свести задачу о динамической связности к следующим операциям с последовательностями вершин: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===Добавление ребра=== | ===Добавление ребра=== | ||
Строка 62: | Строка 42: | ||
[[Файл:Link11.png |thumb|400px|center]] | [[Файл:Link11.png |thumb|400px|center]] | ||
− | + | Пусть хотим добавить ребро <tex>\{c, g\} \</tex> | |
− | + | Выберем любое вхождение вершины <tex>с</tex> в эйлеров обход T1 | |
− | + | Разрежем эйлеров обход T1 на 2 части | |
− | + | A1 - часть обхода до выбранного вхождения вершины <tex>с</tex> | |
− | + | A2 - часть обхода после выбранного вхождения вершины <tex>с</tex> | |
− | + | Аналогично, выберем любое вхождение вершины <tex>g</tex> в эйлеров обход T2 и разрежем его на 2 части B1 и B2 | |
− | + | Соберем результирующий эйлеров обход в порядке A1 B2 B1 A2 | |
− | |||
− | |||
− | + | Чтобы быстро находить место, где разрезать эйлеровы обходы T1 и T2, будем хранить эйлеровы обходы в двоичных деревьях поиска. | |
+ | Ключом вершины, для построения дерева поиска, будет время посещения этой вершины эйлеровым обходом. | ||
+ | Для каждой вершины дерева (T1, T2) будем хранить указатель на вершину в дереве поиска, которая соответствует вхождению вершины дерева в эйлеров обход. | ||
+ | Тогда за O(1) переходим от вершины дерева к вершине дерева поиска, по которой за O(log n) можно будет разделить дерево поиска на 2 части. | ||
===Разрезание ребра=== | ===Разрезание ребра=== |
Версия 00:45, 31 декабря 2016
Содержание
Задача о динамической связности
Задача: |
Для динамически изменяющегося дерева выполнить следующие запросы:
|
Для решения поставленной задачи будем представлять дерево в виде его эйлерова графа, а затем будем работать с эйлеровым обходом (англ.Euler tour tree) этого графа. Это позволит выполнять указанные запросы за .
Представление деревьев в виде эйлерова графа
Для представления дерева в виде эйлерового графа заменим каждое ребро дерева на два ребра и .
Получившийся ориентированный граф будет эйлеровым согласно критерию.
Представим дерево с корнем в вершине
в виде последовательности вершин, посещеннных в порядке эйлерова обхода.Утверждение: |
Последовательность вершин между первым и последним вхождениями вершины в эйлеров обход дерева, представляет эйлеров обход поддерва с корнем в . |
Действительно, при обходе дерева последний раз выйдем из вершины, только после посещения всех вершин ее поддерева. |
Операции c эйлеровыми обходами
Представление деревьев в виде их эйлеровых обходов позволяет свести задачу о динамической связности к следующим операциям с последовательностями вершин:
Добавление ребра
Пусть хотим добавить ребро
Выберем любое вхождение вершины в эйлеров обход T1 Разрежем эйлеров обход T1 на 2 части A1 - часть обхода до выбранного вхождения вершины A2 - часть обхода после выбранного вхождения вершины Аналогично, выберем любое вхождение вершины в эйлеров обход T2 и разрежем его на 2 части B1 и B2 Соберем результирующий эйлеров обход в порядке A1 B2 B1 A2Чтобы быстро находить место, где разрезать эйлеровы обходы T1 и T2, будем хранить эйлеровы обходы в двоичных деревьях поиска. Ключом вершины, для построения дерева поиска, будет время посещения этой вершины эйлеровым обходом. Для каждой вершины дерева (T1, T2) будем хранить указатель на вершину в дереве поиска, которая соответствует вхождению вершины дерева в эйлеров обход. Тогда за O(1) переходим от вершины дерева к вершине дерева поиска, по которой за O(log n) можно будет разделить дерево поиска на 2 части.
Разрезание ребра
Для разбиения дерева на два поддерева путем разрезания ребра
необходимо:- Переподвесить дерево к вершине .
- Разделить дерево на части , где отрезок между первым и последним вхождением вершины .
- Эйлеров обход первого поддерева образуется соединением и , с удалением повторного в месте их соединения.
- Эйлеров обход второго поддерева образует .
В результате получим:
Реализация структуры
Представим последовательность вершин эйлерова обхода в виде сбалансированного двоичного дерева. Будем использовать красно-черное дерево.
Объединение и разделение красно-черных деревьев выполняется за [1].
Для каждой вершины храним указатели на её первое и последнее вхождение в последовательность. Значит, имеем доступ к ним за
.Запрос о принадлежности вершин к одной компоненте связности выполняется за
проверкой лежат ли эти вершины в одном дереве.