Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/2316.html
2316. Count Unreachable Pairs of Nodes in an Undirected Graph
- Difficulty: Medium.
- Related Topics: Depth-First Search, Breadth-First Search, Union Find, Graph.
- Similar Questions: Number of Islands.
Problem
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:
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:
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 (Java, C++, Python)
-
class Solution { public long countPairs(int n, int[][] edges) { DSU d = new DSU(n); HashMap<Integer, Integer> map = new HashMap<>(); for (int[] e : edges) { d.union(e[0], e[1]); } long ans = 0; for (int i = 0; i < n; i++) { int p = d.findParent(i); int cnt = map.containsKey(p) ? map.get(p) : 0; ans += i - cnt; map.put(p, map.getOrDefault(p, 0) + 1); } return ans; } private static class DSU { int[] rank; int[] parent; DSU(int n) { rank = new int[n + 1]; parent = new int[n + 1]; for (int i = 1; i <= n; i++) { parent[i] = i; } } int findParent(int node) { if (parent[node] == node) { return node; } parent[node] = findParent(parent[node]); return findParent(parent[node]); } boolean union(int x, int y) { int px = findParent(x); int py = findParent(y); if (px == py) { return false; } if (rank[px] > rank[py]) { parent[py] = px; } else { parent[px] = py; rank[py]++; } return true; } } } ############ class Solution { private boolean[] vis; private List<Integer>[] g; public long countPairs(int n, int[][] edges) { vis = new boolean[n]; g = new List[n]; Arrays.setAll(g, k -> new ArrayList<>()); for (var e : edges) { int a = e[0], b = e[1]; g[a].add(b); g[b].add(a); } long ans = 0, s = 0; for (int i = 0; i < n; ++i) { if (!vis[i]) { long t = dfs(i); ans += s * t; s += t; } } return ans; } private int dfs(int i) { vis[i] = true; int cnt = 1; for (int j : g[i]) { if (!vis[j]) { cnt += dfs(j); } } return cnt; } }
-
class Solution: def countPairs(self, n: int, edges: List[List[int]]) -> int: def dfs(i): vis.add(i) cnt = 1 for j in g[i]: if j not in vis: cnt += dfs(j) return cnt g = defaultdict(list) for a, b in edges: g[a].append(b) g[b].append(a) vis = set() ans = s = 0 for i in range(n): if i not in vis: t = dfs(i) ans += s * t s += t return ans ############ # 2316. Count Unreachable Pairs of Nodes in an Undirected Graph # https://leetcode.com/problems/count-unreachable-pairs-of-nodes-in-an-undirected-graph/ class DSU: def __init__(self, n): self.graph = list(range(n)) def find(self, x): if self.graph[x] != x: self.graph[x] = self.find(self.graph[x]) return self.graph[x] def union(self, x, y): ux, uy = self.find(x), self.find(y) self.graph[ux] = uy def connected(self, x, y): return self.find(x) == self.find(y) def disconnect(self, x): self.graph[x] = x class Solution: def countPairs(self, n: int, edges: List[List[int]]) -> int: dsu = DSU(n) for a, b in edges: dsu.union(a, b) parents = [0] * n for node in range(n): p = dsu.find(node) parents[p] += 1 res = 0 for node in range(n): p = dsu.find(node) res += n - parents[p] return res // 2
-
class Solution { public: long long countPairs(int n, vector<vector<int>>& edges) { vector<vector<int>> g(n); for (auto& e : edges) { int a = e[0], b = e[1]; g[a].emplace_back(b); g[b].emplace_back(a); } vector<bool> vis(n); function<int(int)> dfs = [&](int i) -> int { vis[i] = true; int cnt = 1; for (int j : g[i]) { if (!vis[j]) { cnt += dfs(j); } } return cnt; }; long long ans = 0, s = 0; for (int i = 0; i < n; ++i) { if (!vis[i]) { long long t = dfs(i); ans += s * t; s += t; } } return ans; } };
-
func countPairs(n int, edges [][]int) (ans int64) { g := make([][]int, n) for _, e := range edges { a, b := e[0], e[1] g[a] = append(g[a], b) g[b] = append(g[b], a) } vis := make([]bool, n) var dfs func(int) int dfs = func(i int) int { vis[i] = true cnt := 1 for _, j := range g[i] { if !vis[j] { cnt += dfs(j) } } return cnt } var s int64 for i := 0; i < n; i++ { if !vis[i] { t := int64(dfs(i)) ans += s * t s += t } } return }
-
function countPairs(n: number, edges: number[][]): number { const g = Array.from({ length: n }, () => []); for (const [a, b] of edges) { g[a].push(b); g[b].push(a); } const vis = new Array(n).fill(false); const dfs = (i: number) => { vis[i] = true; let cnt = 1; for (const j of g[i]) { if (!vis[j]) { cnt += dfs(j); } } return cnt; }; let ans = 0; let s = 0; for (let i = 0; i < n; ++i) { if (!vis[i]) { const t = dfs(i); ans += s * t; s += t; } } return ans; }
-
impl Solution { pub fn count_pairs(n: i32, edges: Vec<Vec<i32>>) -> i64 { let n = n as usize; let mut g = vec![vec![]; n]; let mut vis = vec![false; n]; for e in edges { let u = e[0] as usize; let v = e[1] as usize; g[u].push(v); g[v].push(u); } fn dfs(g: &Vec<Vec<usize>>, vis: &mut Vec<bool>, u: usize) -> i64 { if vis[u] { return 0; } vis[u] = true; let mut cnt = 1; for &v in &g[u] { cnt += dfs(g, vis, v); } cnt } let mut ans = 0; let mut s = 0; for u in 0..n { let t = dfs(&g, &mut vis, u); ans += t * s; s += t; } ans } }
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).