Діаметр дерева#11428

Діаметр дерева (Розбір)

Діаметр дерева — це довжина найдовшого шляху в дереві. Іншими словами, потрібно знайти дві вершини та такі, що відстань між ними максимальна.

Для розв'язання цієї задачі скористаємося таким алгоритмом:

Тоді відстань між вершинами та є максимальною серед усіх пар вершин у дереві і, отже, дорівнює діаметру дерева.

Приклад

Розглянемо дерево з прикладу.

Діаметр дерева дорівнює . Максимальна відстань досягається, наприклад, між вершинами та .

Вправа

Знайдіть діаметр дерева.

Реалізація алгоритму

Зберігатимемо вхідне дерево у списку суміжності . Найкоротші відстані від джерела до кожної вершини зберігатимемо в масиві .

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]);