
Sponsored
Sponsored
The Union-Find data structure can be used to efficiently determine connected components in the graph. By iterating over the edges and performing union operations, we can group nodes into their respective connected components. Once all edges are processed, nodes within the same connected component can reach each other, whereas nodes in different components cannot.
To count the number of unreachable pairs of nodes, compute the size of each component. If the total number of nodes is n, and the size of each component is c_i, the unreachable pairs are given by the sum of c_i * (n - c_i) for all components i.
Time Complexity: O(n + e), where e is the number of edges, due to the union and find operations being amortized nearly constant.
Space Complexity: O(n), for storing parent, rank, and component sizes.
1using System;
2using System.Collections.Generic;
3
4class UnionFind {
5 private int[] parent, rank, size;
6 public UnionFind(int n) {
7 parent = new int[n];
8 rank = new int[n];
9 size = new int[n];
10 for (int i = 0; i < n; i++) {
11 parent[i] = i;
12 size[i] = 1;
13 }
14 }
public int Find(int a) {
if (parent[a] != a) parent[a] = Find(parent[a]);
return parent[a];
}
public void Union(int a, int b) {
int rootA = Find(a);
int rootB = Find(b);
if (rootA != rootB) {
if (rank[rootA] > rank[rootB]) {
parent[rootB] = rootA;
size[rootA] += size[rootB];
} else if (rank[rootA] < rank[rootB]) {
parent[rootA] = rootB;
size[rootB] += size[rootA];
} else {
parent[rootB] = rootA;
rank[rootA]++;
size[rootA] += size[rootB];
}
}
}
public int ComponentSize(int a) {
return size[Find(a)];
}
}
public class UnreachablePairs {
public static int CountUnreachablePairs(int n, int[][] edges) {
UnionFind uf = new UnionFind(n);
foreach (int[] edge in edges) {
uf.Union(edge[0], edge[1]);
}
long totalPairs = (long)n * (n - 1) / 2;
long reachablePairs = 0;
HashSet<int> uniqueRoots = new HashSet<int>();
for (int i = 0; i < n; i++) {
uniqueRoots.Add(uf.Find(i));
}
foreach (int root in uniqueRoots) {
int c_size = uf.ComponentSize(root);
reachablePairs += (long)c_size * (c_size - 1) / 2;
}
return (int)(totalPairs - reachablePairs);
}
public static void Main(string[] args) {
int n = 7;
int[][] edges = { new int[] {0, 2}, new int[] {0, 5}, new int[] {2, 4}, new int[] {1, 6}, new int[] {5, 4} };
Console.WriteLine(CountUnreachablePairs(n, edges));
}
}Using C#'s UnionFind class helps to manage connected node components using find and union operations with path compression and rank optimization. After processing edges, unique roots are used to calculate unreachable pairs by component sizes.
Depth-first search (DFS) can also be employed to explore nodes and determine connected components. By traversing all nodes and initiating DFS for unvisited nodes, the graph's nodes can be segregated into connected sections. Each DFS run marks all connected nodes, constructing a component. Once the components are identified, calculating the number of unreachable pairs becomes straightforward.
The total number of pairs of nodes is (n * (n - 1)) / 2. Subtract the number of pairs within each component from this total to get the number of unreachable pairs.
Time Complexity: O(n + e), where e is the number of edges, using DFS to discover components.
Space Complexity: O(n + e), due to adjacency list and visit tracking.
1import java.util.*;
2
3public class CountUnreachablePairsDFS {
4
5 public static void dfs(int node, boolean[] visited, List<List<Integer>> adjList, int[] componentSize) {
6 visited[node] = true;
7 componentSize[0]++;
8 for (int neighbor : adjList.get(node)) {
9 if (!visited[neighbor]) {
10 dfs(neighbor, visited, adjList, componentSize);
11 }
12 }
13 }
14
15 public static int countUnreachablePairs(int n, int[][] edges) {
16 List<List<Integer>> adjList = new ArrayList<>();
17 for (int i = 0; i < n; i++) {
18 adjList.add(new ArrayList<>());
19 }
20 for (int[] edge : edges) {
21 adjList.get(edge[0]).add(edge[1]);
22 adjList.get(edge[1]).add(edge[0]);
23 }
24
25 boolean[] visited = new boolean[n];
26 long totalPairs = (long)n * (n - 1) / 2;
27 long reachablePairs = 0;
28
29 for (int i = 0; i < n; i++) {
30 if (!visited[i]) {
31 int[] componentSize = {0};
32 dfs(i, visited, adjList, componentSize);
33 reachablePairs += (long)componentSize[0] * (componentSize[0] - 1) / 2;
34 }
35 }
36 return (int)(totalPairs - reachablePairs);
37 }
38
39 public static void main(String[] args) {
40 int n = 7;
41 int[][] edges = {{0, 2}, {0, 5}, {2, 4}, {1, 6}, {5, 4}};
42 System.out.println(countUnreachablePairs(n, edges));
43 }
44}This Java version transforms nodes and edges into adjacency lists for component tracking using DFS. Connected components are formulated for each unvisited node, contributing size information to finalize unreachable pair calculations.