Diametrul unui arbore in C++
Diametrul unui arbore reprezintă lungimea drumului (ca numar de noduri) intre cele mai departate două frunze.
Problema darb – infoarena.ro
In continuare, pentru implementarea algoritmului vom rezolva problema darb de pe infoarena.ro.
Cerinta:
Dandu-se un arbore cu N noduri, sa se determine diametrul acestuia.
Avand urmatorul graf:
Noi trebuie sa aflam distanta cea mai indepartata intre doua noduri. Aceasta distanta este 5 in cazul nostru (drumul 5 – 1 – 2 – 3 – 4). Dar cum putem ajune la acest rezultat?
O prima varianta este sa parcurgem in inaltime fiecare nod in parte si sa retinem cea mai mare distanta rezultata din toate parcurgerile. Aceasta solutie nu este optima din pacate, avand o complexitate de O(N2).
Prima solutie (40 puncte) – Complexitate O(N2)
#include <cstdio> #include <vector> #include <fstream> using namespace std; ifstream fin("darb.in"); ofstream fout("darb.out"); #define MAX_N 100000 int N; vector< int > V[MAX_N]; bool vizitat[MAX_N]; int raspuns; void Read() { fin >> N; for(int i = 1; i < N; i++) { int x, y; fin >> x >> y; --x, --y; V[x].push_back(y); V[y].push_back(x); } } void DFS(int Nod, int Distanta) { if(Distanta > raspuns) raspuns = Distanta; vizitat[Nod] = true; for(unsigned int i = 0; i < V[Nod].size(); i++) { if(!vizitat[V[Nod][i]]) DFS(V[Nod][i], Distanta + 1); } vizitat[Nod] = false; } int main() { Read(); for(int i = 0; i < N; i++) DFS(i, 0); fout << raspuns + 1; }
A doua solutie insa se bazeaza doar pe doua parcurgeri in latime sau adancime. Pornim prima parcurgere dintr-un nod aleatoriu si ne vom oprii intr-un nod ce reprezinta cea mai indepartata frunza din prima parcurgere. Cel de-a doua parcurgere v-a pornii din acest nod si va determina a doua cea mai indepartata frunza.
A doua solutie (problema darb – infoarena.ro)
#include <iostream> #include <fstream> #include <vector> using namespace std; ifstream fin("darb.in"); ofstream fout("darb.out"); const int NLIM = 100005; int N; int nivelMaxim, pozitieNivel; vector < int > Muchii[NLIM]; bool vizitat[NLIM]; void DFS(int Nod, int nivel) { vizitat[Nod] = true; if(nivel > nivelMaxim) { nivelMaxim = nivel; pozitieNivel = Nod; } for(unsigned int i = 0; i < Muchii[Nod].size(); i++) { int Vecin = Muchii[Nod][i]; if(!vizitat[Vecin]) DFS(Vecin, nivel + 1); } } void Reset() { for(int i = 1; i <= N; i++) vizitat[i] = false; } void Read() { int x, y; fin >> N; for(int i = 1; i < N; i++) { fin >> x >> y; Muchii[x].push_back(y); Muchii[y].push_back(x); } DFS(1,0); Reset(); DFS(pozitieNivel, 0); fout << nivelMaxim + 1; } int main() { Read(); return 0; }