union disjoint example graph

PHOTO EMBED

Sat Aug 26 2023 10:34:25 GMT+0000 (Coordinated Universal Time)

Saved by @utp

class DisjointSet:
    def __init__(self, n):
        self.rank = [0] * (n + 1)
        self.parent = list(range(n + 1))
        self.size = [1] * (n + 1)

    def find_upar(self, node):
        if node == self.parent[node]:
            return node
        self.parent[node] = self.find_upar(self.parent[node])
        return self.parent[node]

    def union_by_rank(self, u, v):
        ulp_u = self.find_upar(u)
        ulp_v = self.find_upar(v)
        if ulp_u == ulp_v:
            return
        if self.rank[ulp_u] < self.rank[ulp_v]:
            self.parent[ulp_u] = ulp_v
        elif self.rank[ulp_v] < self.rank[ulp_u]:
            self.parent[ulp_v] = ulp_u
        else:
            self.parent[ulp_v] = ulp_u
            self.rank[ulp_u] += 1

    def union_by_size(self, u, v):
        ulp_u = self.find_upar(u)
        ulp_v = self.find_upar(v)
        if ulp_u == ulp_v:
            return
        if self.size[ulp_u] < self.size[ulp_v]:
            self.parent[ulp_u] = ulp_v
            self.size[ulp_v] += self.size[ulp_u]
        else:
            self.parent[ulp_v] = ulp_u
            self.size[ulp_u] += self.size[ulp_v]
class Solution:
    def Solve(self, n, edge):
        ds = DisjointSet(n)
        cnt_extras = 0
        for u, v in edge:
            if ds.find_upar(u) == ds.find_upar(v):
                cnt_extras += 1
            else:
                ds.union_by_size(u, v)
        cnt_c = sum(1 for i in range(n) if ds.parent[i] == i)
        ans = cnt_c - 1
        if cnt_extras >= ans:
            return ans
        return -1

if __name__ == "__main__":
    V = 9
    edge = [[0, 1], [0, 2], [0, 3], [1, 2], [2, 3], [4, 5], [5, 6], [7, 8]]

    obj = Solution()
    ans = obj.Solve(V, edge)
    print("The number of operations needed:", ans)
content_copyCOPY