Thuật toán đồ thị
Trang này là điểm xuất phát cho nhóm thuật toán đồ thị: hai phép duyệt nền tảng (DFS, sắp xếp topo) được tóm tắt ngay bên dưới, còn mỗi thuật toán lớn có trang riêng với trực giác, ví dụ chạy tay, lỗi thường gặp và bài tập (kể cả đề VOI).
Lộ trình học gợi ý
- Duyệt đồ thị: DFS (bên dưới), rồi BFS cho đường đi ngắn nhất không trọng số, BFS trên lưới và trên không gian trạng thái.
- Đường đi ngắn nhất có trọng số: 0-1 BFS khi cạnh chỉ 0/1, Dijkstra khi trọng số không âm, Bellman-Ford và Floyd-Warshall khi có cạnh âm hoặc cần mọi cặp đỉnh.
- Cây khung và liên thông: Cây khung nhỏ nhất (MST), Bridge và Articulation Point, SCC.
- Cấu trúc đặc biệt và nâng cao: Đồ thị hàm, Đường đi Euler, 2-SAT.
Các trang trong nhóm
| Chủ đề | Mô tả | Trang |
|---|---|---|
| BFS | Đường đi ngắn nhất không trọng số, BFS lưới, đa nguồn, trên không gian trạng thái | BFS |
| 0-1 BFS | Đường đi ngắn nhất khi cạnh chỉ có trọng số 0/1, dùng deque trong | 0-1 BFS |
| Dijkstra | Đường đi ngắn nhất với trọng số không âm, Dijkstra trên đồ thị trạng thái | Dijkstra |
| Bellman-Ford, Floyd-Warshall | Cạnh âm, chu trình âm, đường đi ngắn nhất mọi cặp đỉnh | Bellman-Ford và Floyd-Warshall |
| Cây khung nhỏ nhất | Kruskal, Prim, tính chất lát cắt và chu trình, cây khung lớn nhất | Cây khung nhỏ nhất (MST) |
| Đồ thị hàm | Mỗi đỉnh một cạnh ra: tìm chu trình, đi bước, tua nhanh mô phỏng | Đồ thị hàm |
| Bridge và Articulation Point | Tìm cầu và đỉnh khớp bằng DFS low-link, phân rã song liên thông | Bridge và Articulation Point |
| Đường đi Euler | Đường đi/chu trình qua mọi cạnh đúng một lần (Hierholzer) | Đường đi Euler |
| SCC | Thành phần liên thông mạnh (Tarjan/Kosaraju), nén đồ thị thành DAG | Strongly Connected Components |
| 2-SAT | Thỏa mãn ràng buộc 2 biến qua đồ thị kéo theo + SCC | 2-SAT |
Liên quan: Biểu diễn đồ thị, DSU, DSU có hoàn tác, DP trên đồ thị, Luồng mạng.
DFS:
Đi sâu hết mức theo một nhánh rồi quay lui. Dùng để đếm thành phần liên thông, kiểm tra chu trình, tính kích thước cây con, và là nền của cầu/khớp, SCC.
vector<bool> visited(n, false);
void dfs(int u, vector<vector<int>>& adj) {
visited[u] = true;
for (int v : adj[u]) if (!visited[v]) dfs(v, adj);
}
Với tới trở lên trên đồ thị dạng đường thẳng, đệ quy có thể tràn stack: chuyển sang DFS bằng stack tường minh.
Sắp xếp topo (thuật toán Kahn):
Xếp các đỉnh của DAG sao cho mọi cạnh có đứng trước . Nếu cuối cùng order có ít hơn đỉnh thì đồ thị có chu trình.
vector<int> indegree(n, 0);
for (int u=0; u<n; u++) for (int v:adj[u]) indegree[v]++;
queue<int> q;
for (int i=0; i<n; i++) if (!indegree[i]) q.push(i);
vector<int> order;
while (!q.empty()) {
int u=q.front(); q.pop(); order.push_back(u);
for (int v:adj[u]) if (!--indegree[v]) q.push(v);
}
Trang này có hữu ích không?
Đăng nhập để trả lời
Bình luận