Bài 12.5 - Đếm thành phần liên thông trong Python
Free
Khóa học Python từ Cơ bản đến Nâng cao
Chương 1: Làm quen với Python + Ôn tập I/O, biến, kiểu dữ liệu
Chương 2: Câu lệnh rẽ nhánh, vòng lặp, hàm
Chương 3: Xử lý chuỗi và danh sách nâng cao
Chương 4: Bài kiểm tra Python cơ bản + sửa bài
Chương 5: Duyệt mảng, tìm max/min, đếm
Chương 6: Thuật toán sắp xếp
Chương 7: Prefix Sum + Two Pointers
Chương 8: Backtracking cơ bản
Chương 9: Ôn tập thuật toán cơ bản + kiểm tra
Chương 10: Dynamic Programming cơ bản
Chương 11: Đệ quy và DP nâng cao
Chương 12: Đồ thị cơ bản – DFS, BFS
Chương 13: Đồ thị nâng cao – Dijkstra + Topo sort
Chương 14: Cây – Tree traversal + LCA
Chương 15: Bitmask – Kỹ thuật đại số
Chương 16: Số học + Modular Arithmetic
Chương 17: Class
Chương 18: File và Exception

Bài 12.5 - Đếm thành phần liên thông trong Python
Trong một đồ thị vô hướng, thành phần liên thông (connected component) là một nhóm các đỉnh mà bạn có thể đi từ bất kỳ đỉnh nào đến bất kỳ đỉnh nào khác trong nhóm đó, bằng cách đi qua các cạnh.
Trong bài này, chúng ta sẽ học cách đếm số thành phần liên thông trong đồ thị bằng Python.
Đồ thị ví dụ
Giả sử ta có một đồ thị được biểu diễn dưới dạng danh sách kề:
graph = {
0: [1],
1: [0, 2],
2: [1],
3: [4],
4: [3],
5: []
}
Trong đồ thị trên:
- Thành phần liên thông 1:
{0, 1, 2}
- Thành phần liên thông 2:
{3, 4}
Thành phần liên thông 3:
{5}
(một đỉnh cô lập)Tổng cộng: 3 thành phần liên thông
Cách tiếp cận
Ta sẽ:
- Duyệt qua từng đỉnh.
- Nếu đỉnh đó chưa được thăm, ta sẽ chạy DFS/BFS để đánh dấu toàn bộ thành phần chứa nó.
- Mỗi lần làm như vậy, ta tăng biến đếm số thành phần lên 1.
Cài đặt DFS đếm thành phần liên thông
def count_connected_components(graph):
visited = set()
count = 0
def dfs(node):
visited.add(node)
for neighbor in graph.get(node, []):
if neighbor not in visited:
dfs(neighbor)
for node in graph:
if node not in visited:
dfs(node)
count += 1
return count
Giải thích:
visited
: tập hợp các đỉnh đã duyệt.dfs(node)
: duyệt tất cả các đỉnh trong thành phần liên thông chứanode
.- Mỗi lần gặp đỉnh chưa thăm → tức là bắt đầu một thành phần mới.
Ví dụ minh hoạ
graph = {
0: [1],
1: [0, 2],
2: [1],
3: [4],
4: [3],
5: []
}
print("Số thành phần liên thông:", count_connected_components(graph))
Kết quả:
Số thành phần liên thông: 3
Đúng như mong đợi:
{0,1,2}
,{3,4}
,{5}
Cách khác: Sử dụng BFS
from collections import deque
def count_components_bfs(graph):
visited = set()
count = 0
for node in graph:
if node not in visited:
queue = deque([node])
visited.add(node)
while queue:
current = queue.popleft()
for neighbor in graph.get(current, []):
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
count += 1
return count
Cách dùng BFS cũng tương tự DFS, chỉ khác ở cách duyệt qua hàng đợi thay vì đệ quy.
Độ phức tạp
Thành phần | Giá trị |
---|---|
Thời gian | O(V + E) |
Bộ nhớ | O(V) |
V
: số đỉnhE
: số cạnh
Bài tập mở rộng
- Đếm số thành phần liên thông trong đồ thị có hướng
- In ra các thành phần liên thông thay vì chỉ đếm
- Áp dụng với ma trận kề thay vì danh sách kề
- Biểu diễn đồ thị từ tập cạnh
Tổng kết
- Bài toán đếm thành phần liên thông là một ứng dụng thực tế quan trọng của DFS/BFS.
- Giải pháp đơn giản nhưng mạnh mẽ, có thể mở rộng sang nhiều dạng bài khác.
- Hiểu kỹ bài toán này sẽ giúp bạn dễ dàng tiếp cận với các bài toán liên thông mạnh, tô màu đồ thị, tìm cụm kết nối trong mạng xã hội,...
Khóa học liên quan

3300000
4500000
Học Ngay
Comments