[Solved] Count Unreachable Pairs of Nodes in an Undirected Graph LeetCode Contest Problem

Count Unreachable Pairs of Nodes in an Undirected Graph: You are given an integer n. There is an undirected graph with n nodes, 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 nodes ai and bi.

Return the number of pairs of different nodes that are unreachable from each other.

Example 1:

[Solved] Count Unreachable Pairs of Nodes in an Undirected Graph LeetCode Contest Problem
Input: n = 3, edges = [[0,1],[0,2],[1,2]]
Output: 0
Explanation: There are no pairs of nodes that are unreachable from each other. Therefore, we return 0.

Example 2:

[Solved] Count Unreachable Pairs of Nodes in an Undirected Graph LeetCode Contest Problem
Input: n = 7, edges = [[0,2],[0,5],[2,4],[1,6],[5,4]]
Output: 14
Explanation: There are 14 pairs of nodes that are unreachable from each other:
[[0,1],[0,3],[0,6],[1,2],[1,3],[1,4],[1,5],[2,3],[2,6],[3,4],[3,5],[3,6],[4,6],[5,6]].
Therefore, we return 14.

Constraints:

  • 1 <= n <= 105
  • 0 <= edges.length <= 2 * 105
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • There are no repeated edges.

Solution

Total no. of ways to pick 2 nodes from n nodes = nC2 = n*(n-1)/2;
Here we should not pick 2 nodes from the same component, so we find the number of nodes in each component. And subtract the no. of ways to pick 2 nodes from that component.
To find no. of nodes in a component, we can just do a DFS traversal and maintain a cnt to maintain no. of nodes visited in that dfs call.

class Solution {
public:
    typedef long long ll;
    void dfs(int node, unordered_map<int,vector<int>>& m, ll& cnt, vector<int>& vis){
        vis[node] = 1;
        cnt++;
        for(auto& i: m[node]){
            if(vis[i]==0) dfs(i,m,cnt,vis);   
        }
    }
    long long countPairs(int n, vector<vector<int>>& edges) {
        unordered_map<int,vector<int>> m; // making adjacency list
        for(int i=0;i<edges.size();i++){
            m[edges[i][0]].push_back(edges[i][1]);
            m[edges[i][1]].push_back(edges[i][0]);
        }
        ll ans = ((ll)n*(n-1))/2;
        vector<int> vis(n,0);
        for(int i=0;i<n;i++){
            if(vis[i]==0){ // as node is not visited, we find the no. of nodes in current component.
                ll cnt = 0;
                dfs(i,m,cnt,vis);
                ans -= (cnt*(cnt-1))/2;
            }
        }
        return ans;
    }
};
class Solution:
    def countPairs(self, n: int, edges: List[List[int]]) -> int:
        vis = [True]*n
        adj = [[] for i in range(n)]
        for i in edges:
            adj[i[0]].append(i[1])
            adj[i[1]].append(i[0])
        components = []
        def dfs(v):
            if not vis[v]:
                return
            vis[v] = False
            components[-1] += 1
            for i in adj[v]:
                dfs(i)
        
        for vtx in range(n):
            if vis[vtx]:
                components.append(0)
                dfs(vtx)
        
        ans = 0
        curr = n
        for i in components:
            ans += (curr-i)*i
            curr -= i
        return ans
    private int[] id, sz;
    private Set<Integer> roots; 
    public long countPairs(int n, int[][] edges) {
        id = new int[n];
        sz = new int[n];
        roots = new HashSet<>();
        for (int i = 0; i < n; ++i) {
            roots.add(i);
            id[i] = i;
            sz[i] = 1;
        }
        for (int[] e : edges) {
            union(e[0], e[1]);
        }
        long pairs = 0;
        for (int r : roots) {
            n -= sz[r];
            pairs += 1L * sz[r] * n;
        }
        return pairs;
    }
    private void union(int x, int y) {
        int rx = find(x), ry = find(y);
        if (rx != ry) {
            if (sz[rx] > sz[ry]) {
                sz[rx] += sz[ry];
                id[ry] = id[rx];
                roots.remove(ry);
            }else {
                sz[ry] += sz[rx];
                id[rx] = id[ry];
                roots.remove(rx);
            }
        }
    }
    private int find(int x) {
        while (x != id[x]) {
            x = id[x];
        }
        return x;
    } 

Happy Learning – If you require any further information, feel free to contact me.

Share your love
Saurav Hathi

Saurav Hathi

I'm currently studying Bachelor of Computer Science at Lovely Professional University in Punjab.

📌 Nodejs and Android 😎
📌 Java

Articles: 444

Leave a Reply

Your email address will not be published. Required fields are marked *