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 [Solved] Count Unreachable Pairs of Nodes in an Undirected Graph LeetCode Contest Problem](https://assets.leetcode.com/uploads/2022/05/05/tc-3.png)
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 [Solved] Count Unreachable Pairs of Nodes in an Undirected Graph LeetCode Contest Problem](https://assets.leetcode.com/uploads/2022/05/05/tc-2.png)
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.