Діаметр дерева — це довжина найдовшого шляху в дереві. Іншими словами, потрібно знайти дві вершини та такі, що відстань між ними максимальна.
Для розв'язання цієї задачі скористаємося таким алгоритмом:
Спочатку виконаємо обхід у глибину, починаючи з будь-якої вершини дерева, наприклад, вершини . Під час цього обходу знайдемо вершину, яка знаходиться на максимальній відстані від початкової точки. Позначимо цю вершину як .
Далі виконаємо ще один обхід у глибину, цього разу починаючи з вершини . У результаті цього обходу знайдемо вершину, найвіддаленішу від , і позначимо її як .
Тоді відстань між вершинами та є максимальною серед усіх пар вершин у дереві і, отже, дорівнює діаметру дерева.
Приклад
Розглянемо дерево з прикладу.
Діаметр дерева дорівнює . Максимальна відстань досягається, наприклад, між вершинами та .
Вправа
Знайдіть діаметр дерева.
Реалізація алгоритму
Зберігатимемо вхідне дерево у списку суміжності . Найкоротші відстані від джерела до кожної вершини зберігатимемо в масиві .
vector<vector<int>> g;
vector<int> dist;Функція dfs виконує обхід у глибину з вершини . Найкоротша відстань від джерела до вершини дорівнює . Батьком вершини у обході в глибину є .
void dfs(int v, int d, int p = -1)
{Збережемо найкоротшу відстань від джерела до вершини у dist[v].
dist[v] = d;Переберемо всі ребра (v, to). Для кожного сина to вершини (де не є батьком ) запустимо обхід у глибину. Відстань від джерела до вершини дорівнюватиме d + 1.
for (int to : g[v])
if (to != p) dfs(to, d + 1, v);
}Основна частина програми. Зчитаємо вхідні дані.
scanf("%d", &n);
g.resize(n + 1);
dist.resize(n + 1);Побудуємо неорієнтоване дерево.
for (i = 1; i < n; i++)
{
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}Знайдемо найкоротші відстані від вершини до всіх інших вершин. Найвіддаленіша від неї вершина — це .
dfs(1, 0, -1);
a = max_element(dist.begin(), dist.begin() + n + 1) –
dist.begin();Знайдемо найкоротші відстані від вершини до всіх інших вершин. Найвіддаленіша від неї вершина — це .
dfs(a, 0, -1);
b = max_element(dist.begin(), dist.begin() + n + 1) –
dist.begin();Виведемо діаметр дерева — найкоротшу відстань від до .
printf("%d\n", dist[b]);