Разбор
Выполним поиск в глубину, начиная с любой вершины, например, с вершины . Найдём вершину, наиболее удалённую от , и обозначим её как вершину . Затем запустим поиск в глубину из вершины и найдём вершину, которая будет наиболее удалённой от . Обозначим её как вершину . Тогда расстояние между вершинами и будет максимальным и равно диаметру дерева.
Пример
Рассмотрим дерево из примера.
Диаметр дерева равен . Наибольшее расстояние достигается, например, для вершин и .
Упражнение
Найдите диаметр дерева.
Реализация алгоритма
Входное дерево храним в списке смежности . Кратчайшие расстояния от источника до вершин сохраняем в массиве .
vector<vector<int>> g; vector<int> dist;
Функция dfs выполняет поиск в глубину из вершины . Кратчайшее расстояние от источника до вершины равно . Предком вершины при поиске в глубину является .
void dfs(int v, int d, int p = -1) {
Сохраняем в кратчайшее расстояние от источника до вершины .
dist[v] = d;
Перебираем все ребра . Для каждого сына вершины (где не является предком ) запускаем поиск в глубину. Расстояние от источника до вершины будет равно .
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]);