3339 – Disjoint1
Se consideră un graf cu N
noduri numerotate de la 1
la N
și M
operații de trei tipuri:
1 x y
– se adaugă în graf muchia(x, y)
. Dacă muchia există deja, operația nu se efectuează2 x y
– întrebare: nodurilex
șiy
se află sau nu în aceeași componentă conexă?3
– întrebare: care este numărul maxim de noduri dintr-o componentă conexă?
Cerința[edit | edit source]
Trebuie să răspundeți la toate întrebările de tip 2
și 3
.
Date de intrare[edit | edit source]
Programul citește de la tastatură numerele N
și M
, iar pe următoarele M
linii se află operațiile date fie prin trei valori de forma op x y
(pentru operațiile de tip 1
și 2
), fie printr-o singură valoare 3
(pentru operațiile de tip 3
).
Date de ieșire[edit | edit source]
Programul va afișa pe ecran, pe câte o linie, răspunsul la fiecare întrebare de tip 2
și 3
. Dacă la o întrebare 2 x y
răspunsul este afirmativ, adică x
și y
se află în aceeași componentă conexă, atunci veți afișa DA
, iar în caz contrar veți afișa NU
.
Restricții și precizări[edit | edit source]
3 ≤ N ≤ 32.000
3 ≤ M ≤ 300.000
- va exista cel puțin o operație de fiecare tip.
Exemplul 1[edit | edit source]
Input:
6 6
1 1 4
1 3 6
2 4 6
1 1 3
2 4 6
3
Output:
NU
DA
4
Exemplul 2[edit | edit source]
Input:
99999999 6
1 1 4
1 3 6
2 4 6
1 1 3
2 4 6
3
Output:
Invalid input. Please ensure that 3 ≤ N ≤ 32,000 and 3 ≤ M ≤ 300,000.
Rezolvare[edit | edit source]
<syntaxhighlight lang="python3" line="1"> def verify_conditions(N, M):
return 3 <= N <= 32000 and 3 <= M <= 300000
class UnionFind:
def __init__(self, n): self.parent = list(range(n + 1)) self.rank = [0] * (n + 1) self.size = [1] * (n + 1) self.max_size = 1
def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x]
def union(self, x, y): root_x = self.find(x) root_y = self.find(y)
if root_x != root_y: if self.rank[root_x] < self.rank[root_y]: root_x, root_y = root_y, root_x self.parent[root_y] = root_x self.size[root_x] += self.size[root_y] self.max_size = max(self.max_size, self.size[root_x]) if self.rank[root_x] == self.rank[root_y]: self.rank[root_x] += 1
def main():
N = int(input()) M = int(input())
if not verify_conditions(N, M): print("Invalid input. Please ensure that 3 ≤ N ≤ 32,000 and 3 ≤ M ≤ 300,000.") return
union_find = UnionFind(N)
for _ in range(M): input_values = input().split() operation = int(input_values[0])
if operation == 1: x, y = int(input_values[1]), int(input_values[2]) union_find.union(x, y) elif operation == 2: x, y = int(input_values[1]), int(input_values[2]) result = "DA" if union_find.find(x) == union_find.find(y) else "NU" print(result) elif operation == 3: print(union_find.max_size)
if __name__ == "__main__":
main()
</syntaxhighlight>