Đánh giá độ phức tạp của thuật toán dfs năm 2024
Thuật toán duyệt đồ thị ưu tiên chiều rộng Show Thuật toán duyệt đồ thị ưu tiên chiều rộng (Breadth-first search - BFS) là một trong những thuật toán tìm kiếm cơ bản và thiết yếu trên đồ thị. Mà trong đó, những đỉnh nào gần đỉnh xuất phát hơn sẽ được duyệt trước. Ứng dụng của $BFS$ có thể giúp ta giải quyết tốt một số bài toán trong thời gian và không gian tối thiểu. Đặc biệt là bài toán tìm kiếm đường đi ngắn nhất từ một đỉnh gốc tới tất cả các đỉnh khác. Trong đồ thị không có trọng số hoặc tất cả trọng số bằng nhau, thuật toán sẽ luôn trả ra đường đi ngắn nhất có thể. Ngoài ra, thuật toán này còn được dùng để tìm các thành phần liên thông của đồ thị, hoặc kiểm tra đồ thị hai phía, … Ý tưởngVới đồ thị không trọng số và đỉnh nguồn $s$. Đồ thị này có thể là đồ thị có hướng hoặc vô hướng, điều đó không quan trọng đối với thuật toán. Có thể hiểu thuật toán như một ngọn lửa lan rộng trên đồ thị:
Trong mỗi lần lặp của thuật toán, "vòng lửa" lại lan rộng ra theo chiều rộng. Những đỉnh nào gần $s$ hơn sẽ bùng cháy trước. Chính xác hơn, thuật toán có thể được mô tả như sau:
Thuật toán tìm kiếm theo chiều rộng sử dụng một danh sách để chứa những đỉnh đang “chờ” thăm. Tại mỗi bước, ta thăm một đỉnh đầu danh sách, loại nó ra khỏi danh sách và cho những đỉnh kề với nó chưa được thăm xếp hàng vào cuối danh sách. Thuật toán sẽ kết thúc khi danh sách rỗng. Thuật toánThuật toán sử dụng một cấu trúc dữ liệu hàng đợi (queue) để chứa các đỉnh sẽ được duyệt theo thứ tự ưu tiên chiều rộng. Bước 1: Khởi tạo
Bước 2: Lặp lại các bước sau cho đến khi hàng đợi rỗng:
Bước 3: Truy vết tìm đường đi. Mô tả
Cài đặtCấu trúc dữ liệu:
Truy vết
Các đặc tính của thuật toánNếu sử dụng một ngăn xếp (stack) thay vì hàng đợi (queue) thì ta sẽ thu được thứ tự duyệt đỉnh của thuật toán tìm kiếm theo chiều sâu (Depth First Search – DFS). Đây chính là phương pháp khử đệ quy của $DFS$ để cài đặt thuật toán trên các ngôn ngữ không cho phép đệ quy. Định lí: Thuật toán $BFS$ cho ta độ dài đường đi ngắn nhất từ đỉnh nguồn tới mọi đỉnh (với khoảng cách tới đỉnh $u$ bằng $d[u]$). Trong thuật toán $BFS$, nếu đỉnh $u$ xa đỉnh nguồn hơn đỉnh $v$, thì $u$ sẽ được thăm trước.
Định lý Bắt tay (Handshaking lemma)Định lý: Trong một đồ thị bất kỳ, tổng số bậc của tất cả các đỉnh bằng gấp đôi số cạnh của đồ thị.
Hệ quả: Trong đồ thị, số lượng đỉnh bậc lẻ luôn là một số chẵn.
Nhận xét:
Tham khảo: Handshaking_lemma Độ phức tạp thuật toánĐộ phức tạp thời gianGọi $|V|$ là số lượng đỉnh và $|E|$ là số lượng cạnh của đồ thị. Trong quá trình $BFS$, cách biểu diễn đồ thị có ảnh hưởng lớn tới chi phí về thời gian thực hiện giải thuật :
Độ phức tạp không gianTại mọi thời điểm, trong hàng đợi (queue
Ứng dụng BFS để xác định thành phần liên thôngBài toán 1BDFS - Đếm số thành phần liên thông Đề bàiCho đơn đồ thị vô hướng gồm $n$ đỉnh và $m$ cạnh $(1 \le n, m \le 10^5)$, các đỉnh được đánh số từ $1$ tới $n$. Tìm số thành phần liên thông của đồ thị. Ý tưởngMột đồ thị có thể liên thông hoặc không liên thông. Nếu đồ thị liên thông thì số thành phần liên thông của nó là $1$. Điều này tương đương với phép duyệt theo thủ tục $BFS$ được gọi đến đúng một lần. Nếu đồ thị không liên thông (số thành phần liên thông lớn hơn $1$) ta có thể tách chúng thành những đồ thị con liên thông. Điều này cũng có nghĩa là trong phép duyệt đồ thị, số thành phần liên thông của nó bằng số lần gọi tới thủ tục $BFS$. Thuật toánThuật toán ứng dụng $BFS$ để xác định thành phần liên thông:
Mô tảCài đặtCấu trúc dữ liệu:
include using namespace std;
const int maxN = 1e5 + 7;
int n, m, components = 0;
bool visit[maxN];
vector include using namespace std;
const int maxN = 1e5 + 7;
int n, m, components = 0;
bool visit[maxN];
vector Đánh giáTa cũng có thể sử dụng thuật toán tìm kiếm theo chiều sâu (Depth First Search – DFS) để kiểm tra đồ thị hai phía. |