1601 - Ascensiune

From Bitnami MediaWiki

Cerința[edit | edit source]

Înainte de a participa la Olimpiada Naționala de Informatică, Zoli s-a decis să se plimbe prin oraș. Orașul în care locuiește Zoli are forma unui arbore, fiecare nod reprezentând o locuință iar deplasarea între acestea se efectuează prin intermediul muchiilor.

Zoli dorește să determine lungimea maximă dintre oricare două locuințe din orașul său.

Date de intrare[edit | edit source]

Fișierul de intrare ascensiuneIN.txt conține pe prima linie numărul n, numărul de locuințe, iar pe următoarele n-1 linii câte două numere naturale a, b separate prin spații, reprezentând posibilitatea de deplasare bidirecțională între două locuințe.

Date de ieșire[edit | edit source]

Fișierul de ieșire ascensiuneOUT.txt va conține pe prima linie un număr natural, reprezentând lungimea dintre cele mai îndepărtate locuințe din oraș.În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări[edit | edit source]

  • 1 ≤ n ≤ 100000
  • Pentru 40% dintre teste, 1 ≤ n ≤ 1000
  • Distanța dintre două locuințe reprezintă numărul minim de locuințe intermediare prin care se poate ajunge de la una la cealaltă, inclusiv locuințele inițiale.

Exemplul 1:[edit | edit source]

ascensiuneIN.txt

8
1 2
1 3
2 4
2 5
3 6
3 7
5 8

ascensiuneOUT.txt

6

Explicație[edit | edit source]

Cele mai îndepărtate două locuințe sunt cele cu numărul de ordine 8, respectiv 6 sau 7. Distanța dintre acestea este de 6 locuințe.

Exemplul 2:[edit | edit source]

ascensiuneIN.txt

1000001
1 2
1 3
2 4
2 5
3 6
3 7
5 8

ascensiuneOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python3" line="1"> class TreeDiameter:

   def __init__(self, n):
       self.n = n
       self.G = [[] for _ in range(n + 1)]
       self.dist = [0] * (n + 1)
       self.viz = [False] * (n + 1)
       self.nod_max = 0
       self.dmax = 0
   def dfs(self, i):
       self.viz[i] = True
       for p in self.G[i]:
           if not self.viz[p]:
               self.dist[p] = self.dist[i] + 1
               if self.dist[p] > self.dmax:
                   self.dmax = self.dist[p]
                   self.nod_max = p
               self.dfs(p)
   def find_diameter(self):
       for i in range(1, self.n):
           x, y = map(int, input_file.readline().split())
           self.G[x].append(y)
           self.G[y].append(x)
       self.dist[1] = 1
       self.dfs(1)
       for i in range(1, self.n + 1):
           self.dist[i] = 0
           self.viz[i] = False
       self.dist[self.nod_max] = 1
       self.dmax = 0
       self.dfs(self.nod_max)
       return self.dmax


def check_constraints(n):

   if 1 <= n <= 100000:
       return True
   else:
       with open("ascensiuneOUT.txt", "w") as os:
           os.write("Datele nu corespund restrictiilor impuse")
       return False


if __name__ == "__main__":

   with open("ascensiuneIN.txt", "r") as input_file:
       n = int(input_file.readline())
       if not check_constraints(n):
           # Exit if constraints are not met
           exit()
       tree_diameter = TreeDiameter(n)
       result = tree_diameter.find_diameter()
   with open("ascensiuneOUT.txt", "w") as os:
       os.write(str(result))

</syntaxhighlight>