-
Notifications
You must be signed in to change notification settings - Fork 77
/
uf.py
72 lines (61 loc) · 1.68 KB
/
uf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class UF:
def __init__(self, n):
self.count = n
self.id = list(range(n))
self.sz = [1] * n
def connected(self, p, q):
return self.find(p) == self.find(q)
# quick-find
# def find(self, p):
# return self.id[p]
# def union(self, p, q):
# pId = self.find(p)
# qId = self.find(q)
# if pId == qId:
# return
# for index, i in enumerate(self.id):
# if i == pId:
# self.id[index] = qId
# self.count -= 1
# quick-union
# def find(self, p):
# while self.id[p] != p:
# p = self.id[p]
# return p
# def union(self, p, q):
# pId = self.find(p)
# qId = self.find(q)
# if pId == qId:
# return
# self.id[pId] = qId
# self.count -= 1
# weighted quick-union
def find(self, p):
while self.id[p] != p:
self.id[p] = self.id[self.id[p]] # path compression
p = self.id[p]
return p
def union(self, p, q):
pId = self.find(p)
qId = self.find(q)
if pId == qId:
return
if self.sz[pId] < self.sz[qId]:
self.id[pId] = qId
self.sz[qId] += self.sz[pId]
else:
self.id[qId] = pId
self.sz[pId] += self.sz[qId]
self.count -= 1
if __name__ == '__main__':
import sys
n = int(sys.stdin.readline())
uf = UF(n)
for line in sys.stdin:
p, q = [int(i) for i in line.split()]
if (uf.connected(p, q)):
continue
else:
uf.union(p, q)
print("%s %s" % (p, q))
print(uf.count, "components")