You are on page 1of 15

LÝ THUYẾT ĐỒ THỊ

GV: Hồ Ngọc Thanh

1. Tính chất cơ bản của cây


⚫ Cây là một đồ thị vô hướng, liên thông, và không có chu trình.
Ví dụ:

Nhận xét: Cây gồm đầy đủ n đỉnh, n-1 cạnh.


⚫ Rừng là một đồ thị vô hướng và không có chu trình. Như vậy, rừng có
thể có nhiều thành phần liên thông và mỗi thành phần liên thông là một cây.
⚫ Định lý nhận biết cây
Cho T = (V, E) là đồ thị vô hướng n đỉnh. Các mệnh đề sau đây là tương
đương:
MĐ1: T là cây (T liên thông và không chứa chu trình).
MĐ2: T không chứa chu trình và có n - 1 cạnh.
MĐ3: T liên thông và có n - 1 cạnh.
MĐ4: T liên thông và mỗi cạnh của nó đều là cầu.
MĐ5: Hai đỉnh bất kỳ của T được nối với nhau bởi đúng một đường đi đơn.
MĐ6: T không chứa chu trình nhưng hễ cứ thêm vào nó một cạnh ta thu
được đúng một chu trình.

2. Cây khung của đồ thị


2.1. Định nghĩa
Cho đồ thị G = (V, E) vô hướng, liên thông. Cây khung của đồ thị G là
một cây T = (V, F) được xây dựng từ G với F⊂E.
T chứa tất cả các đỉnh của G và tập cạnh F (có n-1 cạnh, với n là số đỉnh)
là con của tập F.

Trang 1
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

Người ta còn gọi cây khung là: cây bao trùm hay cây tối đại.
Ví dụ: 2 cây khung của đồ thị G

Đồ thị G Cây khung 1 Cây khung 2


Lưu ý: Đồ thị trên còn có các cây khung khác nữa.

2.2. Thuật toán xây dựng cây khung


Xây dựng cây khung dựa trên thuật toán duyệt đồ thị theo chiều sâu hoặc
theo chiều rộng.
Đầu vào: Đồ thị G ở dạng danh sách kề (mảng) Ke.
Đầu ra: Cây khung T của đồ thị.
Mảng ChuaXet dùng để đánh dấu các đỉnh đã được xét hay chưa.
2.2.1. Xây dựng cây khung theo chiều sâu
Ý tưởng: Bắt đầu duyệt từ một đỉnh v nào đó của đồ thị. Tiếp theo, chọn u
(chưa duyệt) là một đỉnh tùy ý kề với v. Lặp lại quá trình, duyệt từ u cho đến khi
không tìm được đỉnh kề (chưa duyệt) tiếp theo nữa, thì lùi lại đỉnh đã duyệt trước
nó để đi qua nhánh khác. Mỗi lần đi qua một cạnh, thì đưa cạnh đó vào cây.
Ví dụ:
10 Đỉnh v Ke(v)
9
2 1 2, 3
4
2 1, 4
8 3 1, 4, 5, 6
3
1 4 2, 3, 7, 8
6 5 7 5 3, 6
6 3, 5
7 4, 8
8 4, 7, 9, 10
9 8, 10
10 8, 9

Trang 2
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

Bắt đầu từ đỉnh root v=1, thứ tự các đỉnh được duyệt như sau:
10
9
2 4
8
3
1
6 5 7

1→ 2 → 4 → 3 → 5 → 6 → lùi lại 5,3,4


7 → 8 → 9 →10 → lùi lại…đến 1, tất cả đỉnh kề của 1 đã xét
Kết quả: T gồm các cạnh {(1, 2), (2, 4), (4, 3), (3, 5), (5, 6), (4, 7), (7, 8),
(8, 9), (9, 10)}. Cây T như sau
10
9
2 4
8
3
1
6 5 7

Mã giả cho thuật toán:


void Tree_DFS(v)
{
ChuaXet[v] = 0; //v đã xét
for (u ∈ Ke(v)) //với mỗi u kề với v
if (ChuaXet[u]) //nếu u chưa xét
{
T = T ∪ (v, u); //đưa cạnh (v, u) vào cây T
Tree_DFS(u); //xây dựng cây con của T với gốc là u
}
}
void main()
{

Trang 3
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

for (v ∈ V) ChuaXet[v] = 1;
T = ∅;
Tree_DFS(root); //root là đỉnh nào đó của đồ thị
}
2.2.2. Xây dựng cây khung theo chiều rộng
Ý tưởng: Bắt đầu từ một đỉnh v bất kỳ (mức 0), duyệt đỉnh v. Sau đó duyệt
các đỉnh kề (mức 1) của v. Tiếp tục duyệt các đỉnh kề (mức 2, mà chưa duyệt) của
các đỉnh mức 1 (theo thứ tự đã duyệt trước đó). Mỗi lần duyệt, đưa cạnh nối từ
đỉnh kề mức sau với đỉnh mức kế trước vào cây T. Cứ tiếp tục cho đến hết mức.
Ví dụ:

Mức 2 Mức 4
Mức 1 10
9
2 4
Mức 3
8
1
3

7
6 5
- Bắt đầu duyệt từ đỉnh 1 (mức 0).
- Duyệt các đỉnh kề (mức 1) của đỉnh 1: duyệt 2, 3. Đưa các cạnh (1,2),
(1,3) vào T.
- Duyệt các đỉnh kề (mức 2) của các đỉnh mức 1: duyệt 4, 5, 6. Đưa các
cạnh (2,4), (3,5), (3,6) vào T.
- Duyệt các đỉnh kề (mức 3) của các đỉnh mức 2: duyệt 7, 8. Đưa các cạnh
(4,7), (4,8) vào T.
- Duyệt các đỉnh kề (mức 4) của các đỉnh mức 3: duyệt 9, 10. Đưa các cạnh
(8,9), (8,10) vào T.
 Thứ tự các đỉnh đã được duyệt như sau:
1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10

Trang 4
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

Kết quả T gồm các cạnh {(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), (4, 7), (4, 8),
(8, 9), (8, 10) }. T là cây sau

Sử dụng hàng đợi QUEUE: Bắt đầu từ một đỉnh v bất kỳ, duyệt đỉnh v, sau
đó đưa các đỉnh u chưa duyệt mà kề v vào cuối hàng đợi, và đưa các cạnh (u,v)
vào T. Tiếp theo, lấy đỉnh u ở đầu hàng đợi, duyệt u và làm tương tự giống như
với v.
Mã giả cho thuật toán:
void Tree_BFS(v)
{
QUEUE = ∅;
QUEUE ⇐ v; //đưa v vào hàng đợi
ChuaXet[v] = 0; //v đã xét
while (QUEUE != ∅) //Nếu hàng đợi chưa rỗng
{
v ⇐ QUEUE; //lấy phần tử v ở đầu hàng đợi
for (u ∈ Ke(v)) //với mỗi u kề với v
if (ChuaXet[u]) //nếu u chưa xét
{
QUEUE ⇐ u; //đưa u vào cuối hàng đợi
ChuaXet[u] = 0; // u đã xét
T = T ∪ (v,u); //đưa cạnh (v,u) vào cây T
};

Trang 5
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

}
}
void main()
{
for (v ∈ V) ChuaXet[v] = 1;
T = ∅;
Tree_DFS(root); //root là đỉnh nào đó của đồ thị
}
Ví dụ:

Mức 2 Mức 4
Mức 1 10
9
2 4
Mức 3
8
1
3

7
6 5
- Diễn giải ngắn gọn: Bắt đầu duyệt từ đỉnh 1 (mức 0). Nội dung hàng đợi
sẽ thay đổi như sau. Mỗi cột là nội dung của QUEUE sau mỗi lần duyệt 1 đỉnh.
Duyệt 1 2 3 4 5 6 7 8 9 10
3 4 5 6 7 8 10
6 7 8
8
 Thứ tự các đỉnh đã được duyệt như sau:
1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10
Kết quả T gồm các cạnh {(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), (4, 7), (4, 8),
(8, 9), (8, 10) }. T là cây sau

Trang 6
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

3. Tìm cây khung nhỏ nhất


Cây khung nhỏ nhất của đồ thị G là cây khung có tổng trọng số nhỏ nhất.
Cây khung nhỏ nhất được ứng dụng để xây dựng: hệ thống giao thông để
nối các vùng với tổng quãng đường ngắn nhất; hệ thống đường sắt với chi phí
nhỏ nhất nhưng vẫn bảo đảm giao thông giữa các thành phố; mạng máy tính với
chi phí lắp đặt nhỏ nhất,...

3.1. Thuật toán Kruskal


Thuật toán xây dựng tập cạnh F của T = (V, F) từ G = (V, E):
- Sắp xếp các cạnh của G theo thứ tự trọng số tăng dần.
- Bắt đầu với F = Ø.
- Lấy cạnh (từ nhỏ đến lớn) của E cho vào F sao cho không tạo chu trình
trong T. Cạnh nào tạo chu trình thì không lấy.
- Thuật toán dừng lại khi có n-1 cạnh được chọn.
Mã giả cho thuật toán Kruskal:
void Kruskal
{
F = ∅;
while ((số lượng cạnh của F < n-1) && (E != ∅))
{
Chọn e nhỏ nhất ∈ E;
E = E \ {e}; //bỏ cạnh e khỏi E (khỏi G)
if (F ∪ {e} mà không tạo chu trình trong T)

Trang 7
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

F = F ∪ {e}; //cho e vào F (vào T)


}
if (số lượng cạnh của F < n-1)
Xuất “Đồ thị không liên thông”;
}
Ví dụ:
b
c
12 24
5
a d
4 7
3
1
f 20
e
- Các cạnh theo thứ tự trọng số tăng dần:

(d,e) (a,f) (b,f) (c,d) (c,e) (a,b) (f,e) (b,c)


1 3 4 5 7 12 20 24
Thực hiện theo các bước của thuật toán: cạnh tím là cạnh cho vào T
- Chọn cạnh nhỏ nhất (d,e) cho vào T (không tạo chu trình), xóa khỏi G:
b
c
12 24
5
a d
4 7
3
1
f 20
e

- Chọn cạnh nhỏ nhất (a,f) cho vào T (không tạo chu trình), xóa khỏi G:

Trang 8
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

b
c
12 24
5
a d
4 7
3
1
f 20
e

- Chọn cạnh nhỏ nhất (f,b) cho vào T (không tạo chu trình), xóa khỏi G:
b
c
12 24
5
a d
4 7
3
1
f 20
e

- Chọn cạnh nhỏ nhất (c,d) cho vào T (không tạo chu trình), xóa khỏi G:
b
c
12 24
5
a d
4 7
3
1
f 20
e

- Chọn cạnh nhỏ nhất (c,e) cho vào T sẽ tạo chu trình, do đó không thêm
vào T, xóa khỏi G.
- Chọn cạnh nhỏ nhất (a,b) cho vào T sẽ tạo chu trình, do đó không thêm
vào T, xóa khỏi G.

Trang 9
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

b
c
12 24
5
a d
4 7
3
1
f 20
e

- Chọn cạnh nhỏ nhất (e,f) cho vào T (không tạo chu trình), xóa khỏi G.
b
c
12 24
5
a d
4 7
3
1
f 20
e

- T đã có n-1 = 6-1 cạnh (màu tím), nên thuật toán dừng.


- Trình bày ngắn gọn:
Chọn CÂY
cạnh a b c d e f
(d,e)=1 a b c d,e f
(a,f)=3 a,f b c d,e
(b,f)=4 a,f,b c d,e
(c,d)=5 a,f,b c,d,e
(c,e)=7 Tạo chu trình
(a,b)=12 Tạo chu trình
a,f,b,c,d,e
(f,e)=20
ngừng vì đã đủ n-1 cạnh
(b,c)=24
Các cạnh đã được chọn cho cây khung nhỏ nhất:

(d,e) (a,f) (b,f) (c,d) (f,e)


1 3 4 5 20

Trang 10
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

Việc kiểm tra đồ thị không chứa chu trình không hề đơn giản, mà thuật toán
phải kiểm tra trong mỗi vòng lặp. Do đó, có thể tiếp cận bằng cách xây dựng “dần
dần” cây khung nhỏ nhất theo cách sau:
- Coi đồ thị ban đầu có n đỉnh và không có cạnh: một rừng gồm n cây.
- Mỗi lần thêm vào một cạnh theo thứ tự trọng số tăng dần, sao cho 2 đầu
mút của cạnh mới được thêm phải nằm ở 2 cây khác nhau.
- Thuật toán sẽ dừng lại khi có n - 1 cạnh được thêm.

3.2. Thuật toán Prim


Thuật toán xây dựng tập đỉnh VT và tập cạnh F của cây khung T = (VT,F)
- Bắt đầu với một đỉnh u bất kỳ: VT = {u}, và F = ∅.
- Trong các cạnh có 1 đỉnh ∈ VT và 1 đỉnh ∉ VT: chọn cạnh có trọng số
nhỏ nhất.
- Bổ sung cạnh đó vào F và đỉnh tương ứng vào VT.
- Thuật toán dừng lại khi có n - 1 cạnh được chọn (hoặc VT = V).
Ví dụ: Đỉnh bắt đầu là u = a.
VT = {a}, và F = ∅
Có đỉnh b,f∉VT nối với a∈VT. Cạnh (a,f) nhỏ nhất nên chọn nó vào T.
b c
12 24
5
a 4 d
7
3
1
f 2
e

Có đỉnh b∉VT nối với a∈VT; Có đỉnh c,e∉VT nối với f∈VT. Cạnh (e,f)
nhỏ nhất nên chọn nó vào T.

Trang 11
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

b c
12 24
5
a 4 d
7
3
1
f 2
e
Có đỉnh b∉VT nối với a∈VT; Có đỉnh c ∉VT nối với e,f∈VT; Có đỉnh d
∉VT nối với e∈VT. Cạnh (d,e) nhỏ nhất nên chọn nó vào T.
b c
12 24
5
a 4 d
7
3
1
f 2
e
Có đỉnh b∉VT nối với a∈VT; Có đỉnh c ∉VT nối với d,e,f∈VT. Cạnh (c,f)
nhỏ nhất nên chọn nó vào T.
b c
12 24
5
a 4 d
7
3
1
f 2
e
Có đỉnh b∉VT nối với b,c∈VT. Cạnh (b,a) nhỏ nhất nên chọn nó vào T.

Trang 12
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

b c
12 24
5
a 4 d
7
3
1
f 2
e
- Thuật toán dừng lại khi có n - 1 cạnh được chọn (hoặc VT = V).
b c
12 24
5
a 4 d
7
3
1
f 2
e

Mã giả cho thuật toán Prim:


void Prim()
{
F = ∅; VT = {u};
while (số cạnh của F < n-1)
{
Chọn cạnh có trọng số nhỏ nhất: e = { min {a(v1,v2); với v1 ∈ VT)}
&& (v2 ∉ VT) };
F = F ∪ {e};
VT = VT ∪ {v2};
}
}
Nhận xét:
- Thuật toán Kruskal và Prim đều là dạng thuật toán tham lam. Thuật toán
tham lam thực hiện một lựa chọn tối ưu ở mỗi giai đoạn. Việc tối ưu ở mỗi giai

Trang 13
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

đoạn không đảm bảo tạo ra lời giải tối ưu toàn cục. Nhưng 2 thuật toán này đều
là các thuật toán tham lam tạo các lời giải tối ưu toàn cục.
- Thuật toán Kruskal làm việc kém hiệu quả với các đồ thị dày (m ≥ n(n-
1)/2, m là số cạnh, n là số đỉnh đồ thị).
- Tìm cây khung lớn nhất: tạm đổi dấu các trọng số, rồi áp dụng thuật toán
tìm cây khung nhỏ nhất, sau đó đổi dấu lại các trọng số trên cây kết quả.

Trang 14
LÝ THUYẾT ĐỒ THỊ
GV: Hồ Ngọc Thanh

BÀI TẬP
1. Hãy vẽ tất cả các cây khung của đồ thị sau
a b a b

e d c d
2. Áp dụng thuật toán Kruskal, tìm cây khung nhỏ nhất cho đồ thị sau
3
10
2 -3 6
2 4 5

15
6 13 1
-1

1 2
9 7 4
3. Áp dụng thuật toán Prim tìm cây khung nhỏ nhất cho đồ thị sau. Đỉnh chọn
đầu tiên là đỉnh 3.
2
4
2
9 6
1
3
5
1
1 5
1 2 3
4 7
4 9 5

Trang 15

You might also like