[CodingTest] Java: Search! Counting Connected Components in a Graph (Problem P11724)
Solving Problem P11724: Search! Counting Connected Components in an Undirected Graph
Problem Description
Given an undirected graph with N vertices and M edges, the task is to calculate the number of connected components in the graph. A connected component is a subset of vertices such that there is a path between any two vertices within the subset, and the subset is not connected to any other vertices outside of it.
Constraints
- 1 ≤ N ≤ 1,000
- 0 ≤ M ≤ N × (N - 1) / 2
- Each edge is given as two integers, representing vertices u and v.
Input Format
- The first line contains two integers N (number of vertices) and M (number of edges).
- The next M lines contain two integers u and v, representing an undirected edge between vertices u and v.
Output Format
Print a single integer, the number of connected components in the graph.
Example Input and Output
Example 1
Input
6 5
1 2
2 5
5 1
3 4
4 6
Output
2
Explanation
- There are two connected components
- Component 1: {1, 2, 5}
- Component 2: {3, 4, 6}
Example 2
Input
6 8
1 2
2 5
5 1
3 4
4 6
5 4
2 4
2 3
Output
1
Explanation
- There is one connected component containing all vertices: {1, 2, 3, 4, 5, 6}.
Approach: Depth-First Search (DFS)
To solve the problem, we use Depth-First Search (DFS) to traverse each connected component in the graph. The idea is to start at an unvisited vertex, traverse all reachable vertices, and count the number of times we initiate a new traversal.
Key Idea
- Use an adjacency list to represent the graph.
- Maintain a visited array to keep track of visited vertices.
- For each vertex, if it has not been visited, initiate a DFS traversal and increment the connected components count.
Complexity
- Time Complexity: ( O(N + M) )
- Traversing all vertices and edges in the graph.
- Space Complexity: ( O(N + M) )
- Storing the adjacency list and visited array.
Java Implementation
package search;
import java.io.*;
import java.util.*;
public class P11724 {
static ArrayList<Integer>[] A;
static boolean visited[];
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
// Initialize adjacency list and visited array
A = new ArrayList[n + 1];
visited = new boolean[n + 1];
for (int i = 1; i <= n; i++) {
A[i] = new ArrayList<>();
}
// Read edges and populate adjacency list
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken());
int e = Integer.parseInt(st.nextToken());
A[s].add(e);
A[e].add(s); // Undirected graph
}
int count = 0;
// Perform DFS for each unvisited vertex
for (int i = 1; i <= n; i++) {
if (!visited[i]) {
count++;
DFS(i);
}
}
System.out.println(count);
}
static void DFS(int v) {
if (visited[v]) {
return;
}
visited[v] = true;
for (int i : A[v]) {
if (!visited[i]) {
DFS(i);
}
}
}
}
Pseudocode
BEGIN
READ n, m (number of vertices and edges)
CREATE adjacency list A of size n + 1
CREATE visited array of size n + 1, initialized to false
FOR i FROM 1 TO n DO
A[i] = new empty list
END FOR
FOR i FROM 0 TO m DO
READ edge (s, e)
ADD e to A[s]
ADD s to A[e] (undirected graph)
END FOR
SET count = 0
FOR i FROM 1 TO n DO
IF visited[i] IS false THEN
INCREMENT count
CALL DFS(i)
END IF
END FOR
PRINT count
END
FUNCTION DFS(v):
IF visited[v] IS true THEN
RETURN
END IF
SET visited[v] = true
FOR each neighbor i in A[v]:
IF visited[i] IS false THEN
CALL DFS(i)
END IF
END FOR
END FUNCTION
Explanation of the Code
- Graph Representation
- The graph is represented using an adjacency list, which is memory-efficient compared to an adjacency matrix for sparse graphs.
- DFS Traversal
- The DFS function recursively visits all vertices in the current connected component.
- The
visited
array ensures that each vertex is visited only once.
- Counting Connected Components
- For each unvisited vertex, we initiate a DFS traversal and increment the connected components count.
- Output
- The final count of connected components is printed.
Walkthrough with Example
Input:
6 5
1 2
2 5
5 1
3 4
4 6
Steps:
- Build adjacency list
- Vertex 1: [2, 5]
- Vertex 2: [1, 5]
- Vertex 3: [4]
- Vertex 4: [3, 6]
- Vertex 5: [1, 2]
- Vertex 6: [4]
- Perform DFS
- Start at vertex 1, traverse {1, 2, 5} (Component 1).
- Move to vertex 3, traverse {3, 4, 6} (Component 2).
- Count = 2.
Output:
2
Complexity Analysis
- Time Complexity: ( O(N + M) )
- DFS visits each vertex and edge once.
- Space Complexity: ( O(N + M) )
- For the adjacency list and visited array.
Links
- Problem Link: Baekjoon P11724
- Graph Theory Reference: Wikipedia
Leave a comment