Trong r t nhi u ng d ng, cách bi u di n đ th d i d ng danh sách k th ng đ c s d ng. Trong bi u di n này, v i m i đnh v c a đ th chúng ta l u tr danh sách các đnh k v i nó mà ta ký hi u là Ke(v), ngh a là
Ke(v) = { u∈ V: (u, v)∈E},
V i cách bi u di n này, m i đnh i c a đ th , ta làm t ng ng v i m t danh sách t t c các đnh k v i nó và đ c ký hi u là List(i). bi u di n List(i), ta có th dùng các ki u d li u ki u t p h p, m ng ho c danh sách liên k t.
Ví d 5. Danh sách k c a đ th vô h ng trong hình 5.8, đ th có h ng trong hình 5.9 đ c bi u di n b ng danh sách k nh sau: List(i) List(i) nh 1 2 3 nh 1 3 2 2 1 3 4 2 4 5 3 1 2 5 3 4 4 2 5 6 5 1 5 3 4 6 6 4 5
5.3. CÁC THU T TOÁN TÌM KI M TRÊN TH
5.3.1 Thu t toán tìm ki m theo chi u sâu
R t nhi u thu t toán trên đ th đ c xây d ng d a trên vi c duy t t t c các đnh c a đ th sao cho m i đnh đ c vi ng th m đúng m t l n. Nh ng thu t toán nh v y đ c g i là thu t toán tìm ki m trên đ th . Chúng ta c ng s làm quen v i hai thu t toán tìm ki m c b n, đó là duy t theo chi u sâu (Depth First Search) và duy t theo chi u r ng (Breath First Search).
T t ng c b n c a thu t toán tìm ki m theo chi u sâu là b t đ u t i m t đnh v0 nào đó, ch n m t đnh u b t k k v i v0 và l y nó làm đnh duy t ti p theo. Cách duy t ti p theo đ c th c hi n t ng t nh đ i v i đnh v0.
ki m tra vi c duy t m i đnh đúng m t l n, chúng ta s d ng m t m ng g m n
ph n t (t ng ng v i n đnh), n u đnh th i đã đ c duy t, ph n t t ng ng trong m ng có giá tr FALSE. Ng c l i, n u đnh ch a đ c duy t, ph n t t ng ng trong m ng có giá tr TRUE. Thu t toán tìm ki m theo chi u sâu b t đ u t đnh v nào đó s duy t t t c các đnh liên thông v i v. Thu t toán có th đ c mô t b ng th t c đ qui DFS()
trong đó: chuaxet - là m ng các giá tr logic đ c thi t l p giá tr TRUE void DFS(int v){
Th m_ nh(v); chuaxet[v] = FALSE; for u ∈ke(v) { if (chuaxet[u] ) DFS( v); } } Th t c DFS() s th m t t c các đnh cùng thành ph n liên thông v i v m i đnh đúng m t l n. đ m b o duy t t t c các đnh c a đ th (có th có nhi u thành ph n liên thông), chúng ta ch c n th c hi n :
for( i=1; i≤n; i++)
chuaxet[i] = TRUE; for( i:=1;i≤ n; i++)
if (chuaxet[i] )
DFS( i);
Chú ý: Thu t toán tìm ki m theo chi u sâu d dàng áp d ng cho đ th có h ng. i v i đ th có h ng, chúng ta ch c n thay các c nh vô h ng b ng các cung c a đ th có h ng.
Ví d 1. Áp d ng thu t toán tìm ki m theo chi u sâu v i đ th trong hình sau:
2 6 8 7 1 4 5 3 10 11 9 12 13 Hình 5.11. th vô h ng G K t qu duy t: 1, 2, 4 , 3, 6, 7, 8, 10, 5, 9, 13, 11, 12
5.3.2. Thu t toán tìm ki m theo chi u r ng (Breadth First Search)
ý r ng, v i thu t toán tìm ki m theo chi u sâu, đnh th m càng mu n s tr thành đnh s m đ c duy t xong. ó là k t qu t t y u vì các đnh th m đ c n p vào stack trong th t c đ qui. Khác v i thu t toán tìm ki m theo chi u sâu, thu t toán tìm ki m theo chi u r ng thay th vi c s d ng stack b ng hàng đ i queue. Trong th t c này, đnh đ c n p vào hàng đ i đ u tiên là v, các đnh k v i v là v1, v2, . . ., vkđ c n p vào queue k ti p. Quá trình đ c th c t ng t v i các đnh trong hàng đ i. Thu t toán d ng khi ta đã duy t h t các đnh k v i đnh trong hàng đ i. Chúng ta có th mô t thu t toán b ng th t c BFS nh d i đây.
chuaxet- m ng ki m tra các đnh đã xét hay ch a;
queue – hàng đ i l u tr các đnh s đ c duy t c a đ th ;
void BFS(int u){
queue = φ;
u <= queue; (*n p u vào hàng đ i*)
chuaxet[u] = false; 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] = false; } } } Th t c BFS s th m t t c các đnh dùng thành ph n liên thông v i u. th m t t c các đnh c a đ th , chúng ta ch c n th c hi n g i t i th t c BFS().
for( u=1; u≤n; u++)
chuaxet[u] = TRUE; for(u=1; u≤n; u++)
if (chuaxet[u])
BFS(u);
Ví d . Áp d ng thu t toán tìm ki m theo chi u r ng v i đ th trong hình 5.11 ta nh n đ c k t qu nh sau:
1, 2, 3, 11, 4, 6, 12, 13, 7, 8, 9, 10, 5;
5.3.3. Ki m tra tính liên thông c a đ th
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: