20260203

20260202

20260201

class UnionFind:
    def __init__(self, n: int):
        # parent[i] = parent of i (if parent[i] == i, i is a root)
        self.parent = list(range(n))
        # size[i] = size of the set whose root is i (only valid for roots)
        self.size = [1] * n

    def find(self, x: int) -> int:
        # Find root with path compression
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, a: int, b: int) -> bool:
        # Union sets containing a and b
        ra = self.find(a)
        rb = self.find(b)

        if ra == rb:
            return False  # already in same set

        # Union by size (attach smaller under larger)
        if self.size[ra] < self.size[rb]:
            ra, rb = rb, ra

        self.parent[rb] = ra
        self.size[ra] += self.size[rb]
        return True

    def same(self, a: int, b: int) -> bool:
        return self.find(a) == self.find(b)

    def component_size(self, x: int) -> int:
        return self.size[self.find(x)]

TODO:


index 202601 202603