You are on page 1of 5

Tổ Tin học – Trường THPT Chuyên Hoàng Lê Kha Ths.

Phạm Trọng Khiêm

Cầu, Khớp và Liên thông mạnh


1. Khái niệm liên thông mạnh
 Một đồ thị có hướng là liên thông mạnh nếu như có đường đi giữa mọi cặp đỉnh.
 Một thành phần liên thông mạnh của một đồ thị có hướng là một đồ thị con tối đại liên thông
mạnh.
 Nếu mỗi thành phần liên thông mạnh được co lại thành một đỉnh, thì đồ thị sẽ trở thành một
đồ thị có hướng không có chu trình.

Một đồ thị cùng các thành phần liên thông mạnh đã được đánh dấu

2. Bài toán định chiều đồ thị


Mã bài: DINHCHIEU_ABASIC
Cho đồ thị vô hướng G có n đỉnh và m cạnh. Hãy tìm cách thay mỗi cạnh của đồ thị bằng
một cung định hướng để đồ thị mới có ít thành phần liên thông mạnh nhất.
Input: file DINHCHIEU_ABASIC.INP gồm:
 Dòng đầu gồm 2 số nguyên dương n, m cho biết số đỉnh và số cạnh của đồ thị.
 m dòng tiếp theo: mỗi dòng gồm một cặp số nguyên u, v cho biết có cạnh nối giữa 2 đỉnh u, v.
Output: file DINHCHIEU_ABASIC.OUT gồm:
 m dòng mỗi dòng chứa một cặp số nguyên u, v cho biết có cung nối từ đỉnh u đến đỉnh v theo
thứ tự từ điển.
Ví dụ:
DINHCHIEU_ABASIC.INP DINHCHIEU_ABASIC.OUT
10 14 12
12 23
13 24
23 31
24 36
27 45
36 47
3 10 58
45 69
47 72
48 84
69 9 10
6 10 10 3
85 10 6
9 10

Page 1
Tổ Tin học – Trường THPT Chuyên Hoàng Lê Kha Ths.Phạm Trọng Khiêm

Thuật toán:
Áp dụng thuật toán DFS
1. Mỗi lần xét qua cạnh (u,v) thì ta định chiều luôn cạnh đó thành cung (u,v).
2. Nếu coi một cạnh của đồ thị là hai cung có hướng ngược chiều nhau thì việc định chiều cạnh
(u,v) thành cung (u,v) đồng nghĩa với ta bỏ cung (v,u) của đồ thị. Ta gọi là phép định chiều DFS

Mã giả:

Coding…

Page 2
Tổ Tin học – Trường THPT Chuyên Hoàng Lê Kha Ths.Phạm Trọng Khiêm
Nhận xét:
- Thuật toán định chiều DFS cho ta một rừng cây DFS và các cung ngoài cây, ta gọi các cung này
là các cung ngược.
- Đây là một phương pháp hiệu quả để liệt kê các chu trình cơ sở trên đồ thị. Vừa duyệt, vừa
định chiều, khi duyệt phải cung ngược (u,v) thì ta truy vết đường đi để tìm từ v  u. Sau đó
nối thêm cung (u,v) để được chu trình cơ sở.
- Một đồ thị vô hướng định chiều được thành đồ thị có hướng liên thông mạnh khi mọi cạnh
của đồ thị đều không phải là cầu. Ngược lại, sau khi định chiều sẽ cho ta ít thành phần liên
thông mạnh nhất, các cung ngược sẽ trở thành cung nối giữa 2 thành phần liên thông mạnh.

Page 3
Tổ Tin học – Trường THPT Chuyên Hoàng Lê Kha Ths.Phạm Trọng Khiêm
3. Bài toán liệt kê CẦU, KHỚP của đồ thị
Mã bài: CAUKHOP_ABASIC
Cho đồ thị vô hướng liên thông G gồm n đỉnh và m cạnh. Hãy liệt kê các cạnh là cầu và các đỉnh là
khớp của đồ thị.
 Cạnh cầu: là cạnh nối giữa 2 thành phần liên thông với nhau.
 Đỉnh khớp: là đỉnh mà nếu xóa đỉnh này cùng với các cạnh liên thuộc với đỉnh đó đi, thì sẽ tăng
số thành phần liên thông của đồ thị.
Input: tệp CAUKHOP_ABASIC.INP gồm:
 Dòng 1: Chứa 2 số nguyên n,m (0<n,m <= 10 5)
 m dòng tiếp theo: mỗi dòng chứa một cặp (u,v) cho biết có cạnh nối giữa 2 đỉnh u, v.
Ouput: tệp CAUKHOP_ABASIC.OUT gồm:
 Dòng 1: chứa số nguyên X là số lượng cạnh cầu của đồ thị.
 X dòng tiếp theo: mỗi dòng chứa một cạnh (u,v) là cầu của đồ thị. Xếp theo thứ tự tăng dần
của v.
 Dòng tiếp theo: chứa số nguyên Y là số lượng đỉnh khớp của đồ thị
 Dòng tiếp theo: ghi Y số nguyên là danh sách các đỉnh là khớp của đồ thị, được xếp theo thứ
tự tăng dần.
Ví dụ:
CAUKHOP_ABASIC.INP CAUKHOP_ABASIC.OUT
11 14 3
12 1 2
13 4 7
14 6 9
34 5
35 1 3467
36
38
47
56
58
69
7 10
7 11
10 11

Page 4
Tổ Tin học – Trường THPT Chuyên Hoàng Lê Kha Ths.Phạm Trọng Khiêm
Thuật toán:
Vẫn thực hiện định chiều DFS. Tuy nhiên, ta sẽ thực hiện thêm thao tác đánh số các đỉnh theo thứ
tự duyệt đến.
 Gọi number[u] là số thứ tự của đỉnh u theo cách đánh số đó.
 Gọi low[u] là giá trị number[.] nhỏ nhất của những đĩnh đến được từ nhánh DFS gốc u bằng
một cung ngược. Nghĩa là nếu nhánh DFS gốc u có nhiều cung ngược hướng lên, thì ta lấy
cung ngược cao nhất. Nếu nhánh DFS không chứa cung ngược thì ta cho low[u] = +oo
 Để cập nhật giá trị low[u], trong thủ tục DFS(u), khi xét tất cả các đỉnh v kề với u, định chiều
cạnh (u,v) thành cung (u,v) ta sẽ có 2 trường hợp:
 TH1: Nếu v đã thăm rồi. Khi đó (u,v) là cung ngược đi từ nhánh DFS(u). Ta cực tiểu hóa
low[u] = min(low[u], number[v])
 TH2: Nếu v chưa thăm. Khi đó ta gọi DFS(v). Sau khi thoát DFS(v) thì ta đã xây dựng xong
nhánh DFS gốc v, nằm trên nhánh DFS gốc u. Những cung ngược đi từ nhánh DFS gốc v,
cũng chính là những cung ngược đi từ nhánh DFS gốc u. Ta cực tiểu hóa low[u] =
min(low[u], low[v])

Nhận xét:
 Một cạnh (u,v) là cầu nếu: từ nhánh DFS(v) không có cung ngược đi lên trên v. Vậy (u,v) là
cầu nếu low[v]>= number[v]. Như ví dụ trên ta có (C, F) và (E, H) là cầu.
 Một cạnh (u,v), đỉnh u là khớp nếu: từ nhánh DFS(v) không có cung ngược đi lên trên u.
Khi đó low[v] >= number[u]. Nghĩa là nếu loại bỏ u thì v không thể đến được các đỉnh tiền
bối của u. Trong hình trên thì B, C, E, F là khớp. Nếu u là gốc của cây DFS có từ 2 nhánh
con trở lên thì u cũng là khớp.

Code: Tham khảo code sách chuyên quyển 1 phần “ứng dụng của BFS và DFS”. Cần lưu ý:
Dùng 3 mảng:
cha[u]: lưu đỉnh cha trực tiếp kề với u.
Number[u]: lưu thứ tự duyệt đến của u trong thuật toán DFS
Low[u]: lưu số hiệu đỉnh ngược cao nhất (Number[.] nhỏ nhất) mà từ u có thể đi đến.

Page 5

You might also like