Cthulhu, Journey, Longest Path of a Tree, Three Paths on a Tree
Autor(es):
Solução:
if (conexo == true && num_arestas == num_vertices)
cout << “FHTAGN !”;
else
cout << “NO”;
Com a configuração atual da árvore, podemos perceber que, para cada caminho em nossa árvore enraizada, temos um nó que é o ponto mais alto, as raízes das sub-árvores;
Assim, podemos calcular, para cada nó u, o comprimento do maior caminho que tem como ponto mais alto o nó u.
Portanto, a estratégia é, sabendo a altura das sub- árvores de cada filho, basta selecionar as duas maiores alturas, somá-las e guardar a soma máxima, representando o diâmetro máximo;
Nossa PD será um vetor das alturas, height[n], com height[u] = altura da sub-árvore u, ou seja, o comprimento máximo do nó u para qualquer folha.
Recorrência:
Confira na GIF abaixo:
int main() {
cin >> n;
adj = vector<vi>(n + 1);
for (ll i = 0; i < n - 1; i++) {
ll u, v;
cin >> u >> v;
add_edge(u, v);
}
height = vi(n + 1, 1);
diameter = 0;
dfs(1, -1);
cout << diameter << "\n";
return 0;
}
ll dfs(ll u, ll parent) {
ll h1, h2;
h1 = h2 = 0;
for (auto v : adj[u]) {
if (v != parent) {
height[u] = max(height[u], dfs(v, u) +
1);
if (height[v] > h2) {
h2 = height[v];
if (h2 > h1)
swap(h1, h2);
}
}
}
diameter = max(diameter, h1 + h2);
return height[u];
}
1. Calcular o diâmetro da árvore salvando as posições que fazer parte do
mesmo
a. Se o diâmetro for igual ao tamanho da árvore:
cout << diâmetro << diam[0] << diam[1] << diam.back();
b. Senão, passamos por cada um dos nós pertencentes ao diâmetro e
calculamos a distância de cada uma delas em relação aos seus filhos, ou seja
até a folha, salvando a folha
cout << diametro + max_dist << diam[0] << max_folha << diam.back();