Sunteți pe pagina 1din 4

Diametrul unui arbore in C++ (problema

darb – infoarena.ro)
By Matraguna Mihai Last updated mart. 23, 2018

 0

 Share

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:

Diagrama diametrul unui arbore


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)

1 #include    <cstdio>
2 #include    <vector>
3 #include    <fstream>
4  
5 using namespace std;
6  
7 ifstream fin("darb.in");
8 ofstream fout("darb.out");
9  
10 #define MAX_N 100000
11  
12 int N;
13  
14 vector< int > V[MAX_N];
15 bool vizitat[MAX_N];
16 int raspuns;
17  
18 void Read()
19 {
20     fin >> N;
21     for(int i = 1; i < N; i++)
22     {
23         int x, y;
24         fin >> x >> y;
25         --x, --y;
26         V[x].push_back(y);
27         V[y].push_back(x);
28     }
29 }
30  
31 void DFS(int Nod, int Distanta)
32 {
33     if(Distanta > raspuns)
34         raspuns = Distanta;
35  
36     vizitat[Nod] = true;
37     for(unsigned int i = 0; i < V[Nod].size(); i++)
38     {
39         if(!vizitat[V[Nod][i]])
40             DFS(V[Nod][i], Distanta + 1);
41     }
42  
43     vizitat[Nod] = false;
44 }
45  
46  
47 int main()
48 {
49     Read();
50  
51     for(int i = 0; i < N; i++)
52         DFS(i, 0);
53  
54     fout << raspuns + 1;
55 }
Diametrul unui arbore

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)

1 #include    <iostream>
2 #include    <fstream>
3 #include    <vector>
4  
5 using namespace std;
6  
7 ifstream fin("darb.in");
8 ofstream fout("darb.out");
9  
10 const int NLIM = 100005;
11  
12 int N;
13 int nivelMaxim, pozitieNivel;
14 vector  < int > Muchii[NLIM];
15  
16 bool vizitat[NLIM];
17  
18 void DFS(int Nod, int nivel)
19 {
20     vizitat[Nod] = true;
21     if(nivel > nivelMaxim)
22     {
23         nivelMaxim = nivel;
24         pozitieNivel = Nod;
25     }
26     for(unsigned int i = 0; i < Muchii[Nod].size(); i++)
27     {
28         int Vecin = Muchii[Nod][i];
29         if(!vizitat[Vecin])
30             DFS(Vecin, nivel + 1);
31     }
32 }
33  
34 void Reset()
35 {
36     for(int i = 1; i <= N; i++)
37         vizitat[i] = false;
38 }
39  
40 void Read()
41 {
42     int x, y;
43     fin >> N;
44     for(int i = 1; i < N; i++)
45     {
46         fin >> x >> y;
47         Muchii[x].push_back(y);
48         Muchii[y].push_back(x);
49     }
50     DFS(1,0);
51  
52     Reset();
53  
54     DFS(pozitieNivel, 0);
55     fout << nivelMaxim + 1;
56 }
57  
58 int main() {
59     Read();
60     return 0;
61 }

S-ar putea să vă placă și