Ağacın diametrini iki dəfə dərinlik birinci axtarışı (DFS) ilə tapın.
Çünki ağac əlaqəli bir dövrsüz qrafdir, həm dərinlik birinci axtarışı (DFS), həm də eninə birinci axtarışı (BFS) başlanğıc vertex-dən digər bütün vertexlərə ən qısa məsafələri düzgün tapır.
və iki zirvə olsun ki, aralarındakı məsafə maksimum olsun — yəni ağacın diametrini təşkil edən zirvələr.
Vertex -dan digər bütün zirvələrə ən qısa məsafələri hesablayaq və onları massivinə, vertex -dən isə massivinə qeyd edək.
Beləliklə, hər bir zirvə üçün uzaq gələcək zirvəyə qədər olan ən böyük məsafə belə olur
Misal
Misal üçün verilmiş ağacı nəzərdən keçirək.
Ağacın diametri məsələn, və zirvələri arasında ola bilər.
Alqoritmin həyata keçirilməsi
Girişdəki ağac qonşuluq listi şəklində verilir.
və zirvələrindən olan ən qısa məsafələr və massivlərində saxlanılır.
vector<vector<int>> g;
vector<int> dista, distb;dfs funksiyası vertex -dən dərinlik birinci axtarışı həyata keçirir.
parametri mənbədən vertexinə qədər olan ən qısa məsafəni göstərir.
Nəticələr massivində saxlanılır.
parametri alqoritm tamamlama müddətində vertexinin atası olan vertexi göstərir.
void dfs(int v, int d, vector<int>& dist, int p = -1)
{dist[v]-də mənbədən vertexinə qədər olan ən qısa məsafəni qeyd edirik.
dist[v] = d;Bütün kənarları (v, to) araşdırırıq. vertexinin oğlu olan hər bir vertexi üçün (vertex vertex -nin atası deyil) dərinlik birinci axtarışı həyata keçiririk.
for (int to : g[v])
if (to != p) dfs(to, d + 1, dist, v);
}Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
scanf("%d", &n);
g.resize(n + 1);
dista.resize(n + 1);
distb.resize(n + 1);Qeyri-istiqatlı ağac yaradırıq.
for (i = 1; i < n; i++)
{
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}zirvəsindən olan ən qısa məsafələri tapırıq. Ondan ən uzaq olan zirvə zirvəsidir.
dfs(1, 0, dista, -1);
a = max_element(dista.begin() + 1, dista.begin() + n + 1) - dista.begin();Sonra zirvəsindən olan ən qısa məsafələri hesablayaq və onları massivində saxlayırıq. -dan ən uzaq olan zirvə zirvəsidir. və zirvələri arasındakı məsafə ağacın diametridir.
dfs(a, 0, dista, -1);
b = max_element(dista.begin() + 1, dista.begin() + n + 1) - dista.begin();zirvəsindən olan ən qısa məsafələri hesablayaq və onları massivində saxlayırıq.
dfs(b, 0, distb, -1);Hər bir zirvə üçün ən uzaq zirvəyə qədər olan məsafəni çap edirik.
for (i = 1; i <= n; i++)
printf("%d ", max(dista[i], distb[i]));
printf("\n");Python tətbiqi
Rekursiya üçün steki artırın.
import sys
sys.setrecursionlimit(1000000)dfs funksiyası vertex -dən dərinlik birinci axtarışı həyata keçirir.
parametri mənbədən vertexinə qədər olan ən qısa məsafəni göstərir.
Nəticələr massivində saxlanılır.
parametri alqoritm tamamlama müddətində vertexinin atası olan vertexi göstərir.
def dfs(v, d, dist, p =- 1):dist[v]-də mənbədən vertexinə qədər olan ən qısa məsafəni qeyd edirik.
dist[v] = dBütün kənarları (v, to) araşdırırıq. vertexinin oğlu olan hər bir vertexi üçün (vertex vertex -nin atası deyil) dərinlik birinci axtarışı həyata keçiririk.
for to in g[v]:
if to != p:
dfs(to, d + 1, dist, v)Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.
n = int(input())
g = [[] for _ in range(n + 1)]
dista = [0] * (n + 1)
distb = [0] * (n + 1)Qeyri-istiqatlı ağac yaradırıq.
for _ in range(n - 1):
u, v = map(int, input().split())
g[u].append(v)
g[v].append(u)zirvəsindən olan ən qısa məsafələri tapırıq. Ondan ən uzaq olan zirvə zirvəsidir.
dfs(1, 0, dista)
a = dista.index(max(dista[1:]))Sonra zirvəsindən olan ən qısa məsafələri hesablayaq və onları massivində saxlayırıq. -dan ən uzaq olan zirvə zirvəsidir. və zirvələri arasındakı məsafə ağacın diametridir.
dfs(a, 0, dista)
b = dista.index(max(dista[1:]))zirvəsindən olan ən qısa məsafələri hesablayaq və onları massivində saxlayırıq.
dfs(b, 0, distb)Hər bir zirvə üçün ən uzaq zirvəyə qədər olan məsafəni çap edirik.
result = [max(dista[i], distb[i]) for i in range(1, n + 1)]
print(*result)