Il diametro di un albero è la lunghezza del percorso più lungo nell'albero. In altre parole, dobbiamo trovare due vertici e tali che la distanza tra loro sia massima.
Per risolvere questo problema, utilizziamo il seguente algoritmo:
Innanzitutto, eseguiamo una ricerca in profondità (depth-first search) a partire da un vertice qualsiasi dell'albero, ad esempio il vertice . Durante questo attraversamento, troviamo il vertice che si trova alla distanza massima dal punto di partenza. Indichiamo questo vertice con .
Successivamente, eseguiamo un'altra ricerca in profondità, questa volta a partire dal vertice . Come risultato di questo attraversamento, troviamo il vertice più lontano da e lo indichiamo con .
Allora, la distanza tra i vertici e è la massima tra tutte le coppie di vertici dell'albero e, quindi, è uguale al diametro dell'albero.
Esempio
Consideriamo l'albero dell'esempio.
Il diametro dell'albero è . La distanza massima si ottiene, ad esempio, tra i vertici e .
Esercizio
Trova il diametro dell'albero.
Implementazione dell'algoritmo
Memorizziamo l'albero in input nella lista di adiacenza . Memorizziamo le distanze minime dalla sorgente a ciascun vertice nell'array .
vector<vector<int>> g;
vector<int> dist;La funzione dfs esegue una ricerca in profondità a partire dal vertice . La distanza minima dalla sorgente al vertice è . Il genitore del vertice nella ricerca in profondità è .
void dfs(int v, int d, int p = -1)
{Memorizziamo la distanza minima dalla sorgente al vertice in dist[v].
dist[v] = d;Scorriamo tutti gli archi (v, to). Per ogni figlio to del vertice (dove non è il genitore di ) avviamo una ricerca in profondità. La distanza dalla sorgente al vertice sarà d + 1.
for (int to : g[v])
if (to != p) dfs(to, d + 1, v);
}La parte principale del programma. Leggiamo i dati in input.
scanf("%d", &n);
g.resize(n + 1);
dist.resize(n + 1);Costruiamo un albero non orientato.
for (i = 1; i < n; i++)
{
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}Troviamo le distanze minime dal vertice a tutti gli altri vertici. Il vertice più lontano da esso è .
dfs(1, 0, -1);
a = max_element(dist.begin(), dist.begin() + n + 1) –
dist.begin();Troviamo le distanze minime dal vertice a tutti gli altri vertici. Il vertice più lontano da esso è .
dfs(a, 0, -1);
b = max_element(dist.begin(), dist.begin() + n + 1) –
dist.begin();Stampiamo il diametro dell'albero — la distanza minima da a .
printf("%d\n", dist[b]);