0963 - Bazine: Difference between revisions
Pagină nouă: == Enunț == La ştrandul Junior din oraşul nostru s-au construit <code>n</code> bazine pentru înot. Fiecare bazin a fost dotat cu câte un robinet pentru umplerea acestuia cu apă. Între <code>m</code> perechi distincte de bazine, a fost instalată câte o ţeavă prin care apa din cele două bazine din fiecare pereche să poată circula. Astfel, cele două bazine din pereche pot fi umplute prin deschiderea unui singur robinet. Administratorul bazei a numerotat bazinele... |
No edit summary |
||
| Line 24: | Line 24: | ||
= Exemplul 1 = | = Exemplul 1 = | ||
<code>bazineIN.txt</code> | <code>bazineIN.txt</code> | ||
10 8 | |||
1 6 | 1 6 | ||
4 5 | 4 5 | ||
Latest revision as of 12:58, 7 January 2024
Enunț
La ştrandul Junior din oraşul nostru s-au construit n bazine pentru înot. Fiecare bazin a fost dotat cu câte un robinet pentru umplerea acestuia cu apă. Între m perechi distincte de bazine, a fost instalată câte o ţeavă prin care apa din cele două bazine din fiecare pereche să poată circula. Astfel, cele două bazine din pereche pot fi umplute prin deschiderea unui singur robinet.
Administratorul bazei a numerotat bazinele cu numerele distincte de la 1 la n şi a notat în registrul lui cele m perechi de numere (x1,y1), (x2,y2),…., (xm,ym) corespunzând perechilor de bazine între care a fost instalată câte o ţeavă. Pentru a umple toate bazinele cu apă, administratorul doreşte să deschidă un număr minim de robinete.
Cerinţă.
Scrieţi un program care să citească numerele naturale n şi m, şi cele 2*m numere naturale x1, y1, x2, y2,…., xm, ym, cu semnificația din enunț, şi care să afişeze cel mai mic număr k de robinete pe care trebuie să le deschidă administratorul astfel încât să fie umplute cu apă toate bazinele.
Date de intrare
Fișierul de intrare bazineIN.txt conține pe prima linie numerele n m, iar pe următoarele m linii căte o pereche de numere x y.
Date de ieșire
Fișierul de ieșire bazineOUT.txt va conține pe prima linie numărul k determinat.
Restricții și precizări
10 ≤ n ≤ 1008 ≤ m ≤ 400- nu există două perechi de numere
(x,y),(x’,y’)astfel încâtx=x’şiy=y’saux=y’şiy=x’printre celemperechi citite din fişier 1 ≤ xi ≤ n,1 ≤ yi ≤ n,xi ≠ yi- fiecare bazin poate fi cuplat la unul sau mai multe bazine prin câte o ţeavă, sau la nici un bazin
Exemplul 1
bazineIN.txt
10 8 1 6 4 5 8 6 3 7 9 4 1 8 10 6 1 10
bazineOUT.txt
4
Explicație
Apa din bazinele 1, 6, 8 şi 10 comunică doar între acestea, fiind instalate ţevi. Astfel pentru aceste patru bazine este necesar să se deschidă un singur robinet pentru umplerea lor.
Apa din bazinele 4, 5 şi 9 comunică, deoarece între acestea sunt ţevi. Astfel pentru aceste bazine este necesar să se deschidă un singur robinet.
Pentru bazinele 3 şi 7 între care există teavă, se deschide un singur robinet, cele două bazine nefiind legate prin ţevi de celelalte bazine
Bazinul 2 nu este cuplat cu niciun alt bazin, fiind necesar să se deschidă robinetul acestuia.
În total se deschid doar 4 robinete pentru a alimenta toate bazinele
Exemplul 2
bazineIN.txt
5 5
bazineOUT.txt
Datele nu corespund restrictiilor impuse
Rezolvare<syntaxhighlight lang="python3" line="1"> class Graf:
def __init__(self, varfuri):
self.varfuri = varfuri
self.lista_adiacenta = {i: [] for i in range(1, varfuri + 1)}
def adauga_muchie(self, u, v):
self.lista_adiacenta[u].append(v)
self.lista_adiacenta[v].append(u)
def numar_minim_robinete(self):
vizitate = set()
robinete = 0
for varf in range(1, self.varfuri + 1):
if varf not in vizitate:
robinete += 1
self.dfs(varf, vizitate)
return robinete
def dfs(self, varf, vizitate):
vizitate.add(varf)
for vecin in self.lista_adiacenta[varf]:
if vecin not in vizitate:
self.dfs(vecin, vizitate)
def verifica_restrictii(n, m, perechi):
if not(10 <= n <= 100) or not(8 <= m <= 400):
return False
for i in range(m):
x, y = perechi[i]
if not(1 <= x <= n) or not(1 <= y <= n) or x == y:
return False
for i in range(m):
for j in range(i + 1, m):
if set(perechi[i]) == set(perechi[j]):
return False
return True
if __name__ == "__main__":
with open("bazineIN.txt", "r") as fisier_intrare:
n, m = map(int, fisier_intrare.readline().split())
perechi = [tuple(map(int, fisier_intrare.readline().split())) for _ in range(m)]
if not verifica_restrictii(n, m, perechi):
with open("bazineOUT.txt", "w") as fisier_iesire:
fisier_iesire.write("Datele nu corespund restrictiilor impuse")
else:
graf = Graf(n)
for x, y in perechi:
graf.adauga_muchie(x, y)
with open("bazineOUT.txt", "w") as fisier_iesire:
k = graf.numar_minim_robinete()
fisier_iesire.write(str(k))
</syntaxhighlight>