Алгоритмы на деревьях — различия между версиями
Строка 11: | Строка 11: | ||
Возьмём вершину <tex> u </tex> такую,что <tex>d[u] >= d[t]</tex> для любого <tex>t</tex>.Снова найдём расстояние от <tex>u</tex> до всех остальных вершин.Самое большое расстояние - диаметр дерева. | Возьмём вершину <tex> u </tex> такую,что <tex>d[u] >= d[t]</tex> для любого <tex>t</tex>.Снова найдём расстояние от <tex>u</tex> до всех остальных вершин.Самое большое расстояние - диаметр дерева. | ||
− | Расстояние до остальных вершин | + | Расстояние до остальных вершин будем искать алгоритмом <tex>BFS</tex>. |
== Реализация == | == Реализация == | ||
Строка 19: | Строка 19: | ||
{ | { | ||
v = u = w = 0; | v = u = w = 0; | ||
− | bfs(g,v); | + | d = bfs(g,v); |
for(i = 0; i < n; i++) | for(i = 0; i < n; i++) | ||
if (d[i] > d[u]) | if (d[i] > d[u]) | ||
Строка 35: | Строка 35: | ||
== Обоснование корректности == | == Обоснование корректности == | ||
− | Будем пользоваться свойством,что в любом дереве | + | Будем пользоваться свойством,что в любом дереве больше одного листа.Исключительный случай-дерево из одной вершины,но алгоритм сработает верное и в этом случае. |
Строка 51: | Строка 51: | ||
{{Теорема | {{Теорема | ||
|statement= | |statement= | ||
− | В дереве BFS не существует ребер между вершинами из разных поддеревьев некоторого | + | В дереве BFS не существует ребер между вершинами из разных поддеревьев некоторого их общего предка. |
|proof= | |proof= | ||
Такое же как у дерева dfs. | Такое же как у дерева dfs. | ||
+ | * [http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%85%D0%BE%D0%B4_%D0%B2_%D0%B3%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D1%83,_%D1%86%D0%B2%D0%B5%D1%82%D0%B0_%D0%B2%D0%B5%D1%80%D1%88%D0%B8%D0%BD#.D0.94.D0.B5.D1.80.D0.B5.D0.B2.D0.BE_.D0.BE.D0.B1.D1.85.D0.BE.D0.B4.D0.B0_.D0.B2_.D0.B3.D0.BB.D1.83.D0.B1.D0.B8.D0.BD.D1.83] | ||
}} | }} | ||
Версия 00:05, 24 декабря 2013
Диаметр дерева - максимальная длина (в рёбрах) кратчайшего пути между любыми двумя вершинами. Алгоритм в этой статье находит диаметр в дереве.
Пусть дан граф
Тогда диаметром называется , где — кратчайшнее расстояние между вершинамиАлгоритм
Возьмём любую вершину
и найдём расстояния до всех других вершин.
Возьмём вершину
такую,что для любого .Снова найдём расстояние от до всех остальных вершин.Самое большое расстояние - диаметр дерева. Расстояние до остальных вершин будем искать алгоритмом .Реализация
int diameterTree(graph g) { v = u = w = 0; d = bfs(g,v); for(i = 0; i < n; i++) if (d[i] > d[u]) u = i; bfs(g,u); for(i = 0; i < n; i++) if (d[i] > d[w]) w = i; return d[w]; }
Обоснование корректности
Будем пользоваться свойством,что в любом дереве больше одного листа.Исключительный случай-дерево из одной вершины,но алгоритм сработает верное и в этом случае.
Теорема: |
Искомое расстояние - есть расстояние между двумя листами. |
Доказательство: |
Пусть нет, пусть искомое расстояние - есть расстояние между вершинами | где - не является листом. Т.к. b не является листом, то значит её степень 1 => из неё существует ребро в непосещенную вершину (дважды посетить вершину мы не можем). Лемма доказана.
Запустив BFS от произвольной вершины. Мы получим дерево BFS.
Теорема: |
В дереве BFS не существует ребер между вершинами из разных поддеревьев некоторого их общего предка. |
Доказательство: |
Такое же как у дерева dfs. |
Мы свели задачу к нахождению вершины
, такой, что сумма глубин поддеревьев максимальна.Докажем, что одно из искомых поддеревьев содержит самый глубокий лист. Пусть нет, тогда взяв расстояние от
до глубочайшего листа мы можем улучшить ответ.Таким образом мы доказали, что нам нужно взять вершину
с наибольшей глубиной после первого bfs, очевидно что ей в пару надо сопоставить вершину , что dist(u, w) - . Очевидно, что проблема решается запуском bfs из .
Оценка производительности
Все операции кроме bfs - О(1). BFS работает линейное время,запускаем мы его 2 раза.Получаем O(V+E).