Solução
Esse é um problema de teoria do grafos.
Primeiro montamos um grafo, com arestas bidirecionais entre todo e que tem ligação de superior/inferior. A partir daí é possível ver que que a solução para um vertice seria a distância máxima entre ele e qualquer outro veŕtice, pois como tem rank 1, então se tem distância de , o rank de caso fosse presidente será sua distância, como queremos saber o número de ranks distintos, o vértice de distância máxima apresentará o maior rank, e no seu caminho até , haverão todos os outros ranks merores que . É possível então fazer uma DFS e computar para cada vértice a distância máxima partindo dele. Porém, essa idéia não passaria no tempo, pois realizamos DFS's, cada uma com tempo , tendo então, de tempo para igual a , que não passaria no tempo.
É possível porém computar isso se uma forma diferente.
É uma propriedade de uma arvore que para todo vértice, o vértice mais distânte dele fará parte do diâmetro da árvore. Isso significa que para todo vértice de uma árvore, podemos garatir que o mais distante dele será um dos dois vértices do diâmetro daquela árvore.
Podemos então achar o dois vértices do diâmetro da árvore, e computar a distância de cada um deles para todos os outros. A resposta para o vértice será então o sendo dist_1 e dist_2 as distâncias do diâmetros para os vértice .
Podemos achar os diâmetros em , computar as distâncias partindo deles com duas DFS's em , e para cada achar sua resposta em , obtendo então um tempo .
Código:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
#define ff first | |
#define ss second | |
using namespace std; | |
const int maxn = 500100; | |
typedef pair<int, int> ii; | |
vector<int> v[maxn]; | |
int dist1[maxn]; | |
int dist2[maxn]; | |
ii dfs1(int x, int p) | |
{ | |
ii ans = {0, x}; | |
for (int u : v[x]) { | |
if (u == p) continue; | |
ans = max(ans, dfs1(u, x)); | |
} | |
ans.ff++; | |
return ans; | |
} | |
void dfs2(int *dist, int x, int p) | |
{ | |
for (int u : v[x]) { | |
if (u == p) continue; | |
dist[u] = dist[x]+1; | |
dfs2(dist, u, x); | |
} | |
} | |
int main() | |
{ | |
ios_base::sync_with_stdio(false); | |
cin.tie(0); | |
int n; | |
cin >> n; | |
for (int i = 1; i < n; i++) { | |
int a, b; | |
cin >>a >> b; | |
v[a].push_back(b); | |
v[b].push_back(a); | |
} | |
ii d1 = dfs1(1, 1); | |
ii d2 = dfs1(d1.ss, d1.ss); | |
dfs2(dist1, d1.ss, d1.ss); | |
dfs2(dist2, d2.ss, d2.ss); | |
for (int i = 1; i <= n; i++) { | |
int ans = max(dist1[i], dist2[i]); | |
cout << ans+1 << "\n"; | |
} | |
return 0; | |
} |