what
a.k.a: disjoint set
implementation
functional
parent = list(range(n))
rank = [1] * n
def find(u, parent):
while u != parent[u]:
parent[u] = parent[parent[u]]
u = parent[u]
return u
def union(u, v, parent, rank):
pu = find(u, parent)
pv = find(v, parent)
if pu == pv:
return
parent[pu] = pv
# if rank[pu] > rank[pv]:
# parent[pv] = pu
# elif rank[pu] < rank[pv]:
# parent[pu] = pv
# else:
# parent[pu] = pv
# rank[pv] += 1
# if rank[pu] > rank[pv]:
# parent[pv] = pu
# rank[pu] += rank[pv]
# else:
# parent[pu] = pv
# rank[pv] += rank[pu]
oop
class UnionFind:
def __init__(self, n: int):
# Initialize parent and rank arrays
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x: int) -> int:
# Find the parent of node x. Use Path Compression
while x != self.parent[x]:
self.parent[x] = self.parent[self.parent[x]]
return x
def unite(self, x: int, y: int) -> None:
# Unite two nodes x and y, if they are not already united
px = self.find(x)
py = self.find(y)
if px == py:
return
self.parent[px] = py
# # Union by Rank Heuristic
# if self.rank[px] > self.rank[py]:
# self.parent[py] = px
# elif self.rank[px] < self.rank[py]:
# self.parent[px] = py
# else:
# self.parent[py] = px
# self.rank[px] += 1
# # Union by Count Heuristic
# if self.rank[px] > self.rank[py]:
# parent[py] = px
# rank[px] += rank[py]
# else:
# parent[px] = py
# rank[py] += rank[px]
def is_connected(self, x: int, y: int) -> bool:
# Check if two nodes x and y are connected or not
return self.find(x) == self.find(y)