Problem Link

Description


You are given an integer n. There is an undirected graph with n vertices, numbered from 0 to n - 1. You are given a 2D integer array edges where edges[i] = [ai, bi] denotes that there exists an undirected edge connecting vertices ai and bi.

Return the number of complete connected components of the graph.

A connected component is a subgraph of a graph in which there exists a path between any two vertices, and no vertex of the subgraph shares an edge with a vertex outside of the subgraph.

A connected component is said to be complete if there exists an edge between every pair of its vertices.

 

Example 1:

Input: n = 6, edges = [[0,1],[0,2],[1,2],[3,4]]
Output: 3
Explanation: From the picture above, one can see that all of the components of this graph are complete.

Example 2:

Input: n = 6, edges = [[0,1],[0,2],[1,2],[3,4],[3,5]]
Output: 1
Explanation: The component containing vertices 0, 1, and 2 is complete since there is an edge between every pair of two vertices. On the other hand, the component containing vertices 3, 4, and 5 is not complete since there is no edge between vertices 4 and 5. Thus, the number of complete components in this graph is 1.

 

Constraints:

  • 1 <= n <= 50
  • 0 <= edges.length <= n * (n - 1) / 2
  • edges[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi
  • There are no repeated edges.

Solution


Python3

class DSU:
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.rank = [0 for i in range(n)]
 
    def find(self, x):
        if self.parent[x] == x:
            return self.parent[x]
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
 
    def union(self, u, v):
        pu = self.find(u)
        pv = self.find(v)
 
        if self.rank[pu] < self.rank[v]:
            pu, pv = pv, pu
 
        self.parent[pv] = pu
        self.rank[pu] += self.rank[pv]
    
class Solution:
    def countCompleteComponents(self, n: int, edges: List[List[int]]) -> int:
        uf = DSU(n)
        
        for a, b in edges:
            uf.union(a, b)
 
        res = 0
        
        parents = defaultdict(list)
        E = defaultdict(int)
        
        for node in range(n):
            parents[uf.find(node)].append(node)
        
        for a, b in edges:
            p = uf.find(a)
            
            E[p] += 1
        
        for parent in parents.keys():
            k = len(parents[parent])
            e = E[parent]
            
            if k * (k - 1) // 2 == e:
                res += 1
        
        return res