Đây là bài toán tìm cầu khớp cơ bản đầu tiên cần biết. Ý tưởng thuật toán như sau (nên xem thêm Tài liệu chuyên tin quyển 1): Bắt chước ý tưởng từ thuật toán Tarjan, gọi num[u]
là số thứ tự đỉnh duyệt đến, low[u]
là giá trị thứ tự nhỏ nhất mà trong cây DFS gốc u
.
Tạo thêm mảng pa[u]
là đỉnh cha của u
trong khi duyệt, pa[u] = 0
khi u
là chốt của cây DFS (đỉnh được duyệt đầu tiên).
Ta thực hiện định chiều DFS trong quá trình duyệt dfs tương tự thuật toán Tarjan. Bây giờ vấn đề đặt ra cạnh nào là cầu, đỉnh nào là khớp.
Với cầu: Giả sử với cạnh
(u,v)
vớiu
là cha trực tiếp củav
trong quá trình dfs (u = pa[v]
). Nếu như từv
theo các cung đã định hướng, không có cách lên đượcu
thì(u,v)
là cầu của đồ thịlow[v] >= num[v]
Với khớp: Xét hai trường hợp:
- Khi
u
là chốt của một cây DFS: (pa[u] = 0
) nếu nó có hai nhánh con trong cây DFS đã định hướng thì khi hủy u sẽ tăng số TPLT =>u
là khớp - Khi
u
không là chốt: (pa[u] > 0
) Gọiv
là đỉnh con củau
thì nếu từv
không có cách đi theo cung định hướng lên được các đỉnh trênu
thìu
lúc này là khớplow[v] >= num[u]
. (cách kiểm tra: duyệtv = 1->n
, sau đó xétu
làpa[v]
).
- Khi