M t đ th có th liên thông ho c có th không liên thông. N u đ th là liên thông (s thành ph n liên thông là 1), chúng ta ch c n g i t i th t c DFS() ho c BFS() m t l n. N u đ th là không liên thông, khi đó s thành ph n liên thông c a đ th chính b ng s l n g i t i th t c BFS() ho c DFS(). xác đnh s các thành ph n liên thông c a đ th , chúng ta s d ng m t bi n m i solt đ nghi nh n các đnh cùng m t thành ph n liên thông trong m ng chuaxet:
- N u đnh i ch a đ c duy t, chuaxet[i] có giá tr 0;
- N u đnh i đ c duy t thu c thành ph n liên thông th j=solt, ta ghi nh n
chuaxet[i]=solt;
- Các đnh cùng thành ph n liên thông n u chúng có cùng giá tr trong m ng chuaxet. void BFS(int u){
queue= φ;
u <= queue; (*n p u vào hàng đ i*)
solt = solt+1; chuaxet[u] = solt;(*solt là bi n toàn c c thi t l p giá tr 0*) while (queue ≠φ ) {
queue<=p; (* l y p ra t stack*) Th m_ nh(p);
for v ∈ ke(p) {
if (chuaxet[v] ){
v<= queue; (*n p v vào hàng đ i*)
chuaxet[v] = solt; } } } } 5.3.4. Tìm đ ng đi gi a hai đnh b t k c a đ th
Th t c BFS(s) ho c DFS(s) cho phép ta duy t các đnh cùng m t thành ph n liên thông v i đnh s. Nh v y, n u trong s các đnh liên thông v i s ch a t thì ch c ch n có đ ng đi t đnh sđ n đnh t. N u trong s các đnh liên thông v i đnh s không ch a đnh t
thì không t n t i đ ng đi t đnh s đ n đnh t. Do v y, chúng ta ch c n g i t i th t c
DFS(s) ho c BFS(s) và ki m tra xem đnh t có thu c thành ph n liên thông v i s hay không. D i đây là toàn v n ch ng trình tìm đ ng đi gi a hai đnh c a đ th .
#include <stdio.h> #include <conio.h> #include <io.h> #include <stdlib.h> #include <dos.h> #define MAX 100 #define TRUE 1
#define FALSE 0int n, truoc[MAX], chuaxet[MAX], queue[MAX]; int A[MAX][MAX]; int s, t;
/* Breadth First Search */ void Init(void){
FILE *fp; int i, j;
fp=fopen("lienth.IN", "r"); if(fp==NULL){
printf("\n Khong co file input"); delay(2000);return;
}
fscanf(fp,"%d", &n);
printf("\n Ma tran ke cua do thi:"); for(i=1; i<=n;i++){ printf("\n"); for(j=1; j<=n;j++){ fscanf(fp,"%d", &A[i][j]); printf("%3d", A[i][j]); } } for(i=1; i<=n;i++){ chuaxet[i]=TRUE; truoc[i]=0; } } void Result(void){ printf("\n\n"); if(truoc[t]==0){
printf("\n Khong co duong di tu %d den %d",s,t); getch();
return;
}
printf("\n Duong di tu %d den %d la:",s,t); int j = t;printf("%d<=", t); while(truoc[j]!=s){ printf("%3d<=",truoc[j]); j=truoc[j]; } printf("%3d",s); } void In(void){ printf("\n\n"); for(int i=1; i<=n; i++)
printf("%3d", truoc[i]); }
void BFS(int s) {
int dauQ, cuoiQ, p, u;printf("\n");
dauQ=1;cuoiQ=1; queue[dauQ]=s;chuaxet[s]=FALSE; while (dauQ<=cuoiQ){
u=queue[dauQ]; dauQ=dauQ+1; printf("%3d",u);
if(A[u][p] && chuaxet[p]){ cuoiQ=cuoiQ+1;queue[cuoiQ]=p; chuaxet[p]=FALSE;truoc[p]=u; } } } } void duongdi(void){
int chuaxet[MAX], truoc[MAX], queue[MAX]; Init();BFS(s);Result();
}
void main(void){ clrscr();
printf("\n Dinh dau:"); scanf("%d",&s); printf("\n Dinh cuoi:"); scanf("%d",&t); Init();printf("\n");BFS(s);
n();getch(); Result();getch(); }
5.4. NG I VÀ CHU TRÌNH EULER
Chu trình đ n trong đ th Gđi qua m i c nh c a đ th đúng m t l n đ c g i là chu trình Euler. ng đi đ n trong G đi qua m i c nh c a nó đúng m t l n đ c g i là đ ng đi Euler. th đ c g i là đ th Euler n u nó có chu trình Euler. th có đ ng đi Euler đ c g i là n a Euler.
Rõ ràng, m i đ th Euler đ u là n a Euler nh ng đi u ng c l i không đúng.
Ví d 1. Xét các đ th G1, G2, G3 trong hình 5.12. a b a b a b e e d c d c c d e G1 G2 G3 Hình 5.12. th vô h ng G1, G2, G3.
th G1 là đ th Euler vì nó có chu trình Euler a, e, c, d, e, b, a. th G3 không có chu trình Euler nh ng ch a đ ng đi Euler a, c, d, e, b, d, a, b vì th G3 là n a Euler. G2 không có chu trình Euler c ng nh đ ng đi Euler.
nh lý. th vô h ng liên thông G=<V, E> là đ th Euler khi và ch khi m i đnh c a Gđ u có b c ch n. th vô h ng liên thông G=<V, E> là đ th n a Euler khi và ch khi nó không có quá hai đnh b c l .
tìm m t chu trình Euler, ta th c hi n theo thu t toán sau:
̇ T o m t m ng CE đ ghi đ ng đi và m t stack đ x p các đnh ta s xét. X p vào đó m t đnh tu ý u nào đó c a đ th , ngh a là đnh u s đ c xét đ u tiên.
̇ Xét đnh trên cùng c a ng n x p, gi s đnh đó là đnh v; và th c hi n: X N u v là đnh cô l p thì l y v kh i ng n x p và đ a vào CE;
X N u v là liên thông v i đnh x thì x p x vào ng n x p sau đó xoá b c nh (v, x); ̇ Quay l i b c 2 cho t i khi ng n x p r ng thì d ng. K t qu đ ng đi Euler
đ c ch a trong CE theo th t ng c l i.
Th t c Euler_Cycle sau s cho phép ta tìm chu trình Euler. void Euler_Cycle(int u){
Stack=φ; CE=φ;
u=>Stack; { n p u vào stack}; while (Stack≠φ) {
x= top(Stack); { x là ph n t đ u stack } if (ke(x) ≠φ) {
y = nh đ u trong danh sách ke(x); Stack<=y; { n p y vào Stack}; Ke(x) = Ke(x) \{y};
Ke(y) = Ke(y)\{x}; {lo i c nh (x,y) kh i đ th };
} else { x<= Stack; {l y x ra kh i stack}; CE <=x; { n p x vào CE;} } }
Ví d . Tìm chu trình Euler trong hình 5.13.
a b
4
1 2 3 5 6 7
f 8 c 9 d 10 e
Các b c th c hi n theo thu t toán s cho ta k t qu sau:
B c Giá tr trong stack Giá tr trong CE C nh còn l i
1 F 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 2 f, a 2, 3, 4, 5, 6, 7, 8, 9, 10 3 f, a, c 3, 4, 5, 6, 7, 8, 9, 10 4 f,a,c,f 3, 4, 5, 6, 7, 9, 10 5 f, a, c f 3, 4, 5, 6, 7, 9, 10 6 f, a, c, b f 3, 4, 6, 7, 9, 10 7 f, a, c, b, d f 3, 4, 7, 9, 10 8 f, a, c, b, d,c f 3, 4, 7, 10 9 f, a, c, b, d f, c 3, 4, 7, 10 10 f, a, c, b, d, e f, c 3, 4, 7 11 f, a, c, b, d, e, b f, c 3, 4 12 f, a, c, b, d, e, b, a f, c 3 13 f, a, c, b, d, e, b, a, d f, c 14 f, a, c, b, d, e, b, a f, c, d 15 f, a, c, b, d, e, b f,c,d,a 16 f, a, c, b, d, e f,c,d,a,b 17 f, a, c, b, d f,c,d,a,b,e 18 f, a, c, b f,c,d,a,b,e,d 19 f, a, c f,c,d,a,b,e,d,b 20 f, a f,c,d,a,b,e,d,b,c 21 f f,c,d,a,b,e,d,b,c,a 22 f,c,d,a,b,e,d,b,c,a,f
M t đ th không có chu trình Euler nh ng v n có th có đ ng đi Euler. Khi đó, đ th có đúng hai đnh b c l , t c là t ng các s c nh xu t phát t m t trong hai đnh đó là s l . M t đ ng đi Euler ph i xu t phát t m t trong hai đnh đó và k t thúc đnh kia. Nh v y, thu t toán tìm đ ng đi Euler ch khác v i thu t toán tìm chu trình Euler ch ta ph i xác đnh đi m xu t phát c a đ ng đi.
tìm t t c các đ ng đi Euler c a m t đ th n đnh, m c nh, ta có th dùng k thu t đ qui nh sau:
̇B c 1. T o m ng b có đ dài m + 1 nh m t ng n x p ch a đ ng đi. t b[0]=1, i=1 (xét đnh th nh t c a đ ng đi);
̇B c 2. L n l t cho b[i] các giá tr là đnh k v i b[i-1] mà c nh (b[i-1],b[i])
không trùng v i nh ng c nh đã dùng t b[0] đ n b[i-1]. V i m i giá tr c a b[i], ta ki m tra:
X N u i<m thì t ng i lên 1đ n v (xét đnh ti p theo) và quay l i b c 2. X N u i=m thì dãy b chính là m t đ ng đi Euler.
5.5. NG I VÀ CHU TRÌNH HAMILTON
V i đ th Euler, chúng ta quan tâm t i vi c duy t các c nh c a đ th m i c nh đúng m t l n, thì trong m c này, chúng ta xét đ n m t bài toán t ng t nh ng ch khác nhau là ta ch quan tâm t i các đnh c a đ th , m i đnh đúng m t l n. S thay đ i này t ng nh không đáng k , nh ng th c t có nhi u s khác bi t trong khi gi i quy t bài toán.
nh ngh a. ng đi qua t t c các đnh c a đ th m i đnh đúng m t l n đ c g i là đ ng đi Hamilton. Chu trình b t đ u t i m t đnh v nào đó qua t t c các đnh còn l i m i đnh đúng m t l n sau đó quay tr l i vđ c g i là chu trình Hamilton. th đ c g i là đ th Hamilton n u nó ch a chu trình Hamilton. th ch a đ ng đi Hamilton đ c g i là đ th n a Hamilton.
Nh v y, m t đ th Hamilton bao gi c ng là đ th n a Hamilton nh ng đi u ng c l i không luôn luôn đúng. Ví d sau s minh h a cho nh n xét này.
Ví d . th đ thi hamilton G3, n a Hamilton G2 và G1.
a a b a b
b c c d c d
G1 G2 G3
Hình 5.14. th đ thi hamilton G3, n a Hamilton G2 và G1.
Cho đ n nay, vi c tìm ra m t tiêu chu n đ nh n bi t đ th Hamilton v n còn m , m c dù đây là v n đ trung tâm c a lý thuy t đ th . H n th n a, cho đ n nay c ng v n ch a có thu t toán hi u qu đ ki m tra m t đ th có ph i là đ th Hamilton hay không.
li t kê t t c các chu trình Hamilton c a đ th , chúng ta có th s d ng thu t toán sau: void Hamilton(int k){
(* Li t kê các chu trình Hamilton c a đ th b ng cách phát tri n dãy đnh (X[1], X[2], . . ., X[k-1] ) c a đ th G = (V, E) *)
for y∈ Ke(X[k-1]) {
if ((k==n+1) && (y == v0)) Ghinhan(X[1], X[2], . . ., X[n], v0);
else {
X[k]=y; chuaxet[y] = false; Hamilton(k+1); chuaxet[y] = true;
};
5.6. CÂY BAO TRÙM
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 toá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ê toà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 toán đ c mô t thông qua th t c Kruskal nh sau:
void Kruskal(void) {