cconnected.
Understand the pattern. Find your own way.Find your starting point
Your learning feed/Idea 69 of 218
Ideas this builds on
Graphs69 / 218

Sometimes you need groups, not routes

Picture

Roads are added over time. Repeatedly, you ask whether two towns are connected. You do not need the route itself. A disjoint-set structure stores which group each town belongs to and merges groups when a new road joins them.

Predict

If a new undirected edge connects two vertices already in the same component, does it merge two components? What does it tell you about cycles?

Reveal the reasoning

It does not merge components. There was already a path between the endpoints, so adding that edge closes a cycle. This is the useful test behind Kruskal’s spanning-tree algorithm.

Go deeper: representatives summarize membership
class DisjointSet:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n

    def find(self, x):
        while x != self.parent[x]:
            self.parent[x] = self.parent[self.parent[x]]
            x = self.parent[x]
        return x

    def union(self, a, b):
        a, b = self.find(a), self.find(b)
        if a == b:
            return False
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.parent[b] = a
        self.size[a] += self.size[b]
        return True

groups = DisjointSet(4)
assert groups.union(0, 1)
assert groups.union(1, 2)
assert groups.find(0) == groups.find(2)
assert not groups.union(0, 2)
assert groups.find(3) != groups.find(0)

The parent array represents a forest of group representatives, not the original graph’s road paths. Union by size attaches a smaller representative tree under a larger one. Path halving shortens future representative lookups while preserving membership.

Initialization and space are O(V). With these optimizations, a sequence of operations has amortized O(α(V)) time per operation, where the inverse Ackermann function grows extremely slowly. That is an amortized statement, not a promise that each individual operation does exactly constant work.

For a fixed graph and a few connectivity questions, BFS or DFS may be simpler. Disjoint sets fit repeated merges and membership queries. They do not directly report shortest paths, directed reachability, or handle arbitrary deletions.

Analogy limit: sharing a representative means connected by some path; it does not mean directly adjacent.

Change one rule

Roads can be deleted as well as added. Can this implementation simply “undo a union” locally?

Check the variation

No. Removing an edge may or may not split a component, and the representative forest has discarded the information needed to decide. Consider recomputation or a specialized offline/dynamic connectivity method.

Connect

Minimum spanning trees combine this connectivity test with a greedy edge rule. Recognition distinguishes “same component” from “cheapest route.”