Union Find (Disjoint Set Union)
Use when: Dynamic connectivity, grouping nodes, cycle detection in undirected graphs.
Complexity: O(α(N)) per operation (nearly O(1))
Standard Implementation
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
self.components = n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # path compression
return self.parent[x]
def union(self, x, y):
px, py = self.find(x), self.find(y)
if px == py:
return False # already connected
if self.rank[px] < self.rank[py]:
px, py = py, px
self.parent[py] = px # union by rank
if self.rank[px] == self.rank[py]:
self.rank[px] += 1
self.components -= 1
return True
def connected(self, x, y):
return self.find(x) == self.find(y)Usage
uf = UnionFind(n)
for u, v in edges:
uf.union(u, v)
# number of connected components
print(uf.components)
# check if two nodes are connected
print(uf.connected(0, n-1))Cycle Detection (undirected graph)
def has_cycle(n, edges):
uf = UnionFind(n)
for u, v in edges:
if not uf.union(u, v): # already connected = cycle
return True
return FalseSignals in a Problem
- “Number of connected components”
- “Are these nodes in the same group?”
- Cycle detection in undirected graph
- Kruskal’s MST algorithm