Giải thuật 2: Không đi qua cầu

Một phần của tài liệu Chuyên đề thuật toán đồ thị trong lập trình căn bản (Trang 80 - 84)

D bằn g9 và tớ iA bằng 7 ,E có khoảng cách tới cây hiện tại bằng 15, và F

Giải thuật 2: Không đi qua cầu

Bỏ cây cầu nối B với D, xây cây cầu nối A với C, đồ thị không có đỉnh bậc lẻ nên là đồ thị Euler

Giả sử G=(V,E) là đồ thị vô hướng, liên thông, tất cả các đỉnh đều có bâc chẵn hơn nữa G là hữu hạn. Khi đó, tất cả các đỉnh đều có bậc lớn hơn 1.

Giải thuật 2: Không đi qua cầu

• Một cạnh của đồ thị G được gọi là cầu, nếu khi xóa cạnh đó khỏi đồ thị thì làm tăng số thành phần liên thông của G.

Giải thuật Gọi chu trình cần tìm là C

1. Khởi tạo: Chọn một đỉnh bất kỳ cho vào C. 2. Nếu G không còn cạnh nào thì dừng.

3. Bổ sung: Chọn một cạnh nối đỉnh vừa chọn với một đỉnh kề với nó theo nguyên tắc: chỉ chọn cạnh cầu nếu không

còn cạnh nào khác để chọn. Bổ sung cạnh vừa chọn và đỉnh cuối của nó vào C, xóa cạnh ấy khỏi G. Quay về bước 2.

Hình 4: Đồ thị Euler - Đồ thị nửa Euler (vô hướng)

Bài làm:

Đồ 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 nó có đường đi Euler a, c, d, e, b, d, a, b, vì thế G3 là đồ thị nửa Euler. Đồ thị G2 không có chu trình cũng như đường đi Euler.

Ví Dụ 2:Cho Các đồ thị có hướng H1,H2,H3 tìm chu trình Euler

Hình 5: Đồ thị Euler - Đồ thị nửa Euler (có hướng)

Bài làm:

Đồ thị H2 là đồ thị Euler vì nó có chu trình Euler a, b, c, d, e, a.

Đồ thị H3 không có chu trình Euler nhưng nó có đường đi Euler c, a, b, c, d, b vì thế H3 là đồ thị nửa Euler. Đồ thị H1 không có chu trình cũng như đường đi Euler.

Code Mẫu

// Bai 6: Thuat Toan xac dinh chu trinh Euler tren do thi G Ngôn ngữ lập trình C++ #include <stdio.h> #include <conio.h> #define TRUE 1 #define FALSE 0 #define VAIN 99 #define MAX 10

int G[MAX][MAX]; // Ma Tran ke Dinh-Dinh (co Khuyen) int S[MAX][MAX]; // Ma Tran danh dau Cung da su dung int Pred[MAX]; // Mang Nua-Bac-Trong cua 1 Dinh int Succ[MAX]; // Mang Nua-Bac-Ngoai cua 1 Dinh int path[MAX]; // Mang duong di cua chu trinh // khai bao ham

int N,k,l=0;

//bien toan cuc void ReadData(); void PrintData();

Đường đi Euler 79 int Check(int k); void Euler(); void main() { ReadData(); PrintData(); Euler(); } void ReadData() { int i,j; FILE* f=fopen("c:\\borlandc\\thuvien\\ltdt2\\EU_in.txt","rt"); if (f==NULL) { printf("\nError Loading File!\n"); return; } fscanf(f,"%d",&N);// gia tri dau tien cho biet so dinh cua Do Thi G for(i=1;i<=N;i++)

{

Succ[i]=Pred[i]=0; for(j=1;j<=N;j++) {

S[i][j]=FALSE; // danh dau Cung khong con su dung nua fscanf(f,"%d",&G[i][j]);//lan luot doc cac phan tu MT ke } } fclose(f); for(i=1;i<=N;i++) for(j=1;j<=N;j++) if(G[i][j]>0)

{ S[i][j]=TRUE;Succ[i]++;Pred[j]++;} // Tinh Bac moi Dinh

} void PrintData() { clrscr(); int i,j; printf("\nMa Tran Ke G[%d*%d]:\n",N,N); for(i=1;i<=N;i++) { for(j=1;j<=N;j++) printf("%4d",G[i][j]); printf("\n"); } } void Euler() { FILE *g=fopen("c:\\borlandc\\thuvien\\ltdt2\\EU_out.txt","wt"); int i; for(i=1;i<=N;i++)

int k,ok; // kiem tra va in ra man hinh chu trinh Euler 1 net ve printf("\nKet qua kiem tra xuat phat tu dinh 1:\n");

for(k=2;k<=N;k++) // kiem tra xuat phat tu Dinh 1 {

if((G[1][k]!=0)) // co Cung noi Dinh 1 voi Dinh k {

S[1][k]=FALSE; // danh dau Cung(1,k) da duoc su dung ok=Check(k); // xet tiep Dinh k

if(ok==FALSE)

S[1][k]=TRUE;//duong nay khong nen qua Dinh k=>tra danh dau else // ok==TRUE

{

//printf(" %d",k);//lan luot hien thi nguoc cac Dinh da qua printf("Tong so dinh cua chu trinh: %d\n",l+2);

fprintf(g,"%d\n",l+2);

printf("Cac dinh cua duong di chu trinh:\n"); printf("1 %d ",k); fprintf(g,"1 %d ",k); for(int r=l-1;r>=0;r--) { printf("%d ",path[r]); fprintf(g,"%d ",path[r]); } fclose(g); getch(); return; } } } // end for }

int Check(int k) // tiep tuc kiem tra, xuat phat tu Dinh k {

int i,j,ok;

for(i=1;i<=N;i++) {

if((S[k][i]==TRUE)&&(G[k][i]!=0))//co Cung tu k den cac Dinh con lai ? {

S[k][i]=FALSE;// neu co, danh dau khong su dung lai Cung(k,i) nua ok=Check(i); // xet tiep Dinh i den cac Dinh khac

Đường đi Euler 81

S[k][i]=TRUE;//lan nay khong nen qua Dinh i => bo danh dau else { //printf(" %d",i); path[l]=i; l++; return TRUE; } } }

for(i=1;i<=N;i++) // khi khong con Cung di tu Dinh k nua

for(j=1;j<=N;j++) // quet duyet do thi G xem da het Cung chua?

if(S[i][j]==TRUE) // neu con sot Cung tren Ma Tran danh dau S => return FALSE;//huong di theo Dinh k nay la sai=>chon Dinh k khac return TRUE; // thanh cong, tra ve cac dinh nguoc tren duong di Euler

}

Một phần của tài liệu Chuyên đề thuật toán đồ thị trong lập trình căn bản (Trang 80 - 84)

Tải bản đầy đủ (PDF)

(127 trang)