5.6.1. Khái ni m và đnh nghƿa
Đnh nghƿa 1. Ta gọi cây là đồ thị vô h ớng liên thơng khơng có chu trình. Đồ thị
khơng có chu trình đ ợc gọi là rừng.
Nh v y, rừng là đ th mà mỗi thành ph n liên thơng c a nó là một cây. Ví d . Rừng g m 3 cây trong hình 5.15.
T1 T2 T3
Hình 5.15 . R ng g m 3 cây T1, T2, T3.
Cây đ c coi là d ng đ th đ n gi n nh t c a đ th . Đ nh lý sau đây cho ta một s tính ch t c a cây.
Đnh lý. Giả sử G=<V, E> là đồ thị vô h ớng n đỉnh. Khi đó những khẳng định sau
là t ơng đ ơng
a. G là một cây.
b. G là đ th vô h ớng liên thơng khơng có chu trình. c. G liên thơng và có đúng n-1 c nh.
d. Gi a hai đnh b t kỳ c a G có đúng một đ ng đi. e. G liên thông và mỗi c nh c a nó đ u là c u.
f. G 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.
Đnh nghƿa 2. Cho G là đồ thị vô h ớng liên thông. Ta gọi đồ thị con T của G là một cây bao trùm hay cây khung nếu T thoả mãn hai điều kiện:
g. T là một cây;
h. T p đnh c a T bằng t p đnh c a G.
Đ i với cây bao trùm, chúng ta quan tâm tới nh ng bài toán c b n sau:
Bài toán 1. Cho G=<V, E> là đ th vô h ớng liên thông. Hãy xây dựng một cây bao trùm c a G.
Bài toán 2. Cho G = <V, E> là đ th vơ h ớng liên thơng có trọng s . Hãy tìm cây bao trùm nh nh t c a G.
5.6.2. Tìm m t cây bao trùm trên đ th
Để tìm một cây bao trùm trên đ th vô h ớng liên thơng, có thể s d ng k thu t tìm ki m theo chi u rộng hoặc tìm ki m theo chi u sâu để thực hi n. Gi s ta c n xây dựng một cây bao trùm xu t phát t i đnh u nào đó. Trong c hai tr ng h p, mỗi khi ta đ n đ c
đnh v t c (chuaxet[v] = true) từđnh u thì c nh (u,v) đ c k t n p vào cây bao trùm. Hai k thu t này đ c thể hi n trong hai th t c STREE_DFS(u) và STREE_BFS(v) nh sau:
void STREE_DFS( int u){
/* Tìm ki m theo chi u sâu, áp d ng cho bài toán xây dựng cây bao trùm c a đ th vô h ớng liên
thông G=(V, E); các bi n chuaxet, Ke, T là toàn c c */ chuaxet[u] = true; for v∈ Ke(u) { if (chuaxet[v]){ T = T ∪ (u,v); STREE_DFS(v); } } } void STREE_BFS(int u) { QUUE=φ;
QUEUE<= u; /* đ a u vào hàng đ i*/ chuaxet[u] = false; while (QUEUE≠φ ) { v<= QUEUE; /* l y v kh i hàng đ i */ for p ∈ Ke(v) { if (chuaxet[u]) { QUEUE<= u; chuaxet[u] = false; T = T∪(v, p); } } } } /* Main program */ for u ∈ V { chuaxet[u] = true; T = φ; STREE_BFS(root); }
5.6.3. Tìm cây bao trùm ng n nh t
Bài tốn tìm cây bao trùm nh nh t là một trong nh ng bài toán t i u trên đ th có ng d ng trong nhi u lĩnh vực khác nhau c a thực t . Bài toán đ c phát biểu nh sau:
Cho G=<V, E> là đ th vô h ớng liên thông với t p đnh V = {1, 2, . . ., n } và t p c nh E g m m c nh. Mỗi c nh e c a đ th đ c gán với một s không âm c(e) đ c gọi là
độ dài c a nó. Gi s H = <V, T> là một cây bao trùm c a đ th G. Ta gọi độ dài c(H) c a cây bao trùm H là tổng độ dài các c nh c a nó: =∑∈
T e e c H c( ) ( ). Bài toán đ c đặt ra là, trong s các cây khung c a đ th hãy tìm cây khung có độ dài nh nh t c a đ th .
Để gi i bài toán cây bao trùm nh nh t, chúng ta có thể li t kê tồn bộ cây bao trùm và chọn trong s đó một cây nh nh t. Ph ng án nh v y thực sự khơng kh thi vì s cây bao trùm c a đ th là r t lớn c nn-2, đi u này không thể thực hi n đ c với đ th với s
đnh c ch c.
Để tìm một cây bao trùm chúng ta có thể thực hi n theo các b ớc nh sau:
B ớc 1. Thi t l p t p c nh c a cây bao trùm là φ . Chọn c nh e = (i, j) có độ
dài nh nh t bổ sung vào T.
B ớc 2. Trong s các c nh thuộc E \ T, tìm c nh e = (i1, j1) có độ dài nh nh t sao cho khi bổ sung c nh đó vào T khơng t o nên chu trình. Để thực hi n
đi u này, chúng ta ph i chọn c nh có độ dài nh nh t sao cho hoặc i1∈ T và j1∉ T, hoặc j1∈ T và i1∉ T.
B ớc 3. Kiểm tra xem T đã đ n-1 c nh hay ch a? N u T đ n-1 c nh thì nó chính là cây bao trùm ng n nh t c n tìm. N u ch a đ n-1 c nh thì thực hi n l i b ớc 2.
Ví d . Tìm cây bao trùm nh nh t c a đ th trong hình 5.16. 2 20 4
33 8
1 18 16 9 6
17 14
3 4 5
Hình 5.16. Đ th vô h ng liên thông G=(V, E)
B ớc 1. Đặt T=φ. Chọn c nh (3, 5) có độ dài nh nh t bổ sung vào T.
Buớc 2. Sau ba l n lặp đ u tiên, ta l n l t bổ sung vào các c nh (4,5), (4, 6). Rõ ràng, n u bổ sung vào c nh (5, 6) s t o nên chu trình vì đnh 5, 6 đã có mặt trong T. Tình hu ng t ng tự cũng x y ra đ i với c nh (3, 4) là c nh ti p theo c a dãy. Ti p đó, ta bổ sung hai c nh (1, 3), (2, 3) vào T.
Buớc 3. T p c nh trong T đã đ n-1 c nh: T={ (3, 5 ), (4,6), (4,5), (1,3), (2,3)} chính là cây bao trùm ng n nh t.
5.6.4. Thu t toán Kruskal
Thu t toán xây dựng t p c nh T c a cây khung nh nh t H=<V, T> theo từng b ớc nh sau:
a. S p x p các c nh c a đ th G theo th tự tĕng d n c a trọng s c nh;
b. Xu t phát từ t p c nh T=φ, mỗi b ớc, ta s l n l t duy t trong danh sách các c nh đã đ c s p x p, từ c nh có trọng s nh đ n c nh có trọng s lớn để
tìm ra c nh mà khi bổ sung nó vào T khơng t o thành chu trình trong t p các c nh đã đ c bổ sung vào T tr ớc đó;
c. Thu t toán s k t thúc khi ta thu đ c t p T g m n-1 c nh. Thu t tốn đ c mơ t thông qua th t c Kruskal nh sau:
void Kruskal(void) { T = φ;
While( | T | < (n-1) and (E≠φ )) {
Chọn c nh e ∈E là c nh có độ dài nh nh t; E = E\ {e};
if (T ∪ {e} khơng t o nên chu trình ) T = T ∪ {e};
}
if ( | T | <n-1)
<Đ th không liên thông>; }
5.6.5. Thu t toán Prim
Thu t toán Kruskal làm vi c kém hi u qu đ i với nh ng đ th có s c nh kho ng
m=n(n-1)/2. Trong nh ng tình hu ng nh v y, thu t toán Prim t ra hi u qu h n. Thu t
tốn Prim cịn đ c mang tên là ng i láng gi ng g n nh t. Trong thu t toán này, b t đ u t i một đnh tuỳ ý s c a đ th , n i s với đnh y sao cho trọng s c nh c[s, y] là nh nh t. Ti p theo, từđnh s hoặc y tìm c nh có độ dài nh nh t, đi u này d n đ n đnh th ba z và ta thu đ c cây bộ ph n g m 3 đnh 2 c nh. Quá trình đ c ti p t c cho tới khi ta nh n đ c cây g m n-1 c nh, đó chính là cây bao trùm nh nh t c n tìm.
Trong q trình thực hi n thu t tốn, mỗi b ớc, ta có thể nhanh chóng chọn đnh và c nh c n bổ sung vào cây khung, các đnh c a đ th đ c s đ c gán các nhãn. Nhãn c a một đnh v g m hai ph n, [d[v], near[v]]. Trong đó, ph n th nh t d[v] dùng để ghi nh n
độ dài c nh nh nh t trong s các c nh n i đnh v với các đnh c a cây khung đang xây dựng. Ph n th hai, near[v] ghi nh n đnh c a cây khung g n v nh t. Thu t toán Prim đ c mô t thông qua th t c sau:
void Prim(void) { (*b ớc kh i t o*) Chọn s là một đnh nào đó c a đ th ; VH = { s }; T = φ; d[s] = 0; near[s] = s; For v∈ V\VH { D[v] = C[s, v]; near[v] = s; } (* B ớc lặp *) Stop = False; While (! stop) {
Tìm u∈ V\VH tho mãn : d[u] = min { d[v] với u∈V\VH}; VH = VH∪ {u}; T = T ∪ {u, near[u] };
If (| VH | == n ) { H = (VH, T) là cây khung nh nh t c a đ th ; Stop := TRUE; } Else For (v ∈ V\VH ) { If (d[v] > C[u, v]) { D[v] = C[u, v]; Near[v] = u; } } } 5.7. BÀI TỐN TÌM ĐƯ NG ĐI NG N NH T 5.7.1. Phát bi u bài toán
Xét đ th có h ớng G=<V, E>; trong đó | V| = n, | E | = m. Với mỗi cung (u,v)∈E,
ta đặt t ng ng với nó một s thực A(u,v) đ c gọi là trọng s c a cung. Ta s đặt
A[u,v]=∞ n u (u,v)∉E. N u dãy v0, v1, . . . , vk là một đ ng đi trên G thì [ , ]
1 1
∑= −
p
i Avi vi
đ c gọi là độ dài c a đ ng đi.
Bài tốn tìm đ ng đi ng n nh t trên đ th có h ớng d ới d ng tổng quát có thể đ c phát biểu d ới d ng sau: tìm đ ng đi ng n nh t từ một đnh xu t phát s∈V (đnh ngu n) đ n đnh cu i t∈V (đnh đích). Đ ng đi nh v y đ c gọi là đ ng đi ng n nh t từ
s đ n t, độ dài c a đ ng đi d(s,t) đ c gọi là kho ng cách ng n nh t từ s đ n t (trong
tr ng h p tổng quát d(s,t) có thể âm). N u nh không t n t i đ ng đi từ s đ n t thì độ dài
đ ng đi d(s,t)=∞. N u nh mỗi chu trình trong đ th đ u có độ dài d ng thì trong đ ng
đi ng n nh t s khơng có đnh nào b lặp l i, đ ng đi nh v y đ c gọi là đ ng đi c b n. N u nh đ th t n t i một chu trình nào đó có độ dài âm , thì đ ng đi ng n nh t có thể
khơng xác đnh, vì ta có thểđi qua chu trình âm đó một s l n đ lớn đểđộ dài c a nó nh h n b t kỳ một s thực cho tr ớc nào.
5.7.2. Thu t tốn Dijkstra
Thu t tốn tìm đ ng đi ng n nh t từ đnh s đ n các đnh còn l i đ c Dijkstra đ
ngh áp d ng cho tr ng h p đ th có trọng s khơng âm. Thu t tốn đ c thực hi n trên c s gán nhãn t m th i cho các đnh. Nhãn c a mỗi đnh cho bi t c n trên c a độ dài
đ ng đi ng n nh t tới đnh đó. Các nhãn này s đ c bi n đổi (tính l i) nh một th t c lặp, mà mỗi b ớc lặp một s đnh s có nhãn khơng thay đổi, nhãn đó chính là độ dài
đ ng đi ng n nh t từ s đ n đnh đó. Thu t tốn có thểđ c mô t bằng th tực Dijkstra
nh sau:
void Dijkstra(void) {
(*Đ u vào G=(V, E) với n đnh có ma tr n trọng s A[u,v]≥ 0; s∈V *) (*Đ u ra là kho ng cách nh nh t từ s đ n các đnh còn l i d[v]: v∈V. Truoc[v] ghi l i đnh tr ớc v trong đ ng đi ng n nh t từ s đ n v*) (* B ớc 1: Kh i t o nhãn t m th i cho các đnh*) for (v=1; v≤n; v++){ d[v] = A[s,v]; truoc[v]=s; } d[s]=0; T = V\{s};(*T là t p đnh có nhãn t m th i*) while (T!=φ ) { (* b ớc lặp *)
Tìm đnh u∈T sao cho d[u] = min { d[z] : z∈T} T= T\{u}; (*c đnh nhãn đnh u*);
For (v∈T) { (* Gán l i nhãn cho các đnh trong T*) If ( d[v] > d[u] + A[u, v] ) { d[v] = d[u] + A[u, v]; truoc[v] =u; } } } }
5.7.3. Thu t toán Floy
Để tìm đ ng đi ng n nh t gi a t t c các cặp đnh c a đ th , chúng ta có thể s d ng n l n thu t toán Ford_Bellman hoặc Dijkstra (trong tr ng h p trọng s không âm). Tuy nhiên, trong c hai thu t toán đ c s d ng đ u có độ ph c t p tính tốn lớn (chí ít là O(n3)). Trong tr ng h p tổng quát, ng i ta th ng dùng thu t toán Floy đ c mô t nh sau:
void Floy(){
Input: Đ th cho b i ma tr n trọng s a[i, j], i, j = 1, 2, . . ., n.
Output:- Ma tr n đ ng đi ng n nh t gi a các cặp đnh d[i, j], i, j = 1, 2, . . .,n; d[i,j] là độ dài ng n nh t từ i đ n j.
Ma tr n ghi nh n đ ng đi p[i, j], i, j = 1, 2, . . ., n
p[i, j] ghi nh n đnh đi tr ớc đnh j trong đ ng đi ng n nh t;*) (*b ớc kh i t o*)
for( i=1; i≤; i++) for( j =1; j≤n; j++) { d[i,j] = a[i, j]; p[i,j] = i; } (*b ớc lặp *) for (k=1; k≤n; k++)
for( i=1; i≤n; i++)
for (j =1; j≤n; j++) if (d[i,j] > d[i, k] + d[k, j]) { d[i, j] = d[i, k] + d[k, j]; p[i,j] = p[k, j]; } }
B n đọc có thể tìm th y nh ng cài đặt c thể các thu t tốn trên đ th thơng qua các tài li u [1], [5].
NH NG N I DUNG C N GHI NH
9 N m v ng nh ng khái ni m và đnh nghĩa c b n c a đ th .
9 Hiểu đ c các ph ng pháp biểu di n đ th trên máy tính.
9 N m v ng đ c các thu t tốn tìm ki m trên đ th : thu t tốn tìm ki m theo chi u rộng, thu t tốn tìm ki m theo chi u sâu và ng d ng c a nó trong bài tốn tìm đ ng đi gi a hai đnh c a đ th cũng nh trong tính tốn các thành ph n liên thông c a đ th .
9 N m v ng sự khác bi t gi a đ th Euler và đ th Hamilton cùng với thu t tốn tìm đ ng đi và chu trình trên các đ th Euler & Hamilton.
9 N m v ng bài tốn tìm cây bao trùm & tìm cây bao trùm nh nh t.
9 Hiểu & cài đặt nhu n nhuy n các thu t tốn tìm đ ng đi ngẵn nh t gi a các cặp
BÀI T P CHƯƠNG 5
Bài 1. Cho tr ớc ma tr n k c a đ th . Hãy vi t ch ng trình t o ra danh sách k c a đ
th đó.
Bài 2. Cho tr ớc danh sách k c a đ th , hãy t o nên ma tr n k c a đ th .
Bài 3. Một bàn c 8×8 đ c đánh s theo cách sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
Mỗi ơ có thể coi là một đnh c a đ th . Hai đnh đ c coi là k nhau n u một con vua
đặt ơ này có thể nh y sang ô kia sau một b ớc đi. Ví d : ơ 1 k với ô 2, 9, 10, ô 11 k với 2, 3, 4, 10, 12, 18, 19, 20. Hãy vi t ch ng trình t o ma tr n k c a đ th , k t qu in ra file king.out.
Bài 4. Bàn c 8×8 đ c đánh s nh bài trên. Mỗi ơ có thể coi là một đnh c a đ th . Hai
đnh đ c gọi là k nhau n u một con mã đặt ơ này có thể nh y sang ơ kia sau một n ớc đi. Ví d ơ 1 k với 11, 18, ô 11 k với 1, 5, 17, 21, 26, 28. Hãy vi t ch ng trình l p ma tr n k c a đ th , k t qu ghi vào file ma.out.
Bài 5. Hãy l p ch ng trình tìm một đ ng đi c a con mã trên bàn c từ ô s đ n ô t (s, t
đ c nh p từ bàn phím).
Bài 6. Cho C s d li u ghi l i thông tin v N Tuyến bay (N<=100) c a một hãng hàng khơng. Trong đó, thơng tin v mỗi tuy n bay đ c mô t b i: Điểm kh i hành (departure), điểm đ n (destination), kho ng cách (lenght). Departure, destination là một xâu kí tự độ dài khơng q 32, khơng ch a d u tr ng gi a, Length là một s nh h n 32767.
Ta gọi “Hành trình bay” từđiểm kh i hành A tới điểm đ n B là dãy các hành trình [A, A1, n1], [A1, A2, n2] . . .[Ak, B,nk] với Ai là điểm đ n c a tuy n i nh ng l i là điểm kh i
hành c a tuy n i +1, ni là kho ng cách c a tuy n bay th i (1<=i<k). Trong đó, kho ng cách c a hành trình là tổng kho ng cách c a các tuy n mà hành trình đi qua (n1+n2+. .+nk).
Cho file d li u kiểu text hanhtrinh.in đ c ghi theo từng dòng, s các dòng trong file d li u không v t quá N, trên mỗi dịng ghi l i thơng tin v một tuy n bay, trong đó departure, destination, length đ c phân bi t với nhau b i một hoặc vài d u tr ng. Hãy tìm gi i pháp để tho mãn nhu c u c a khách hàng đi từ A đ n B theo một s tình hu ng sau: