52
BOÄ GIAÙO DUÏC VAØ ÑAØO TAÏO TRÖÔØNG ÑAÏI HOÏC DAÂN LAÄP CÖÛU LONG KHOA COÂNG NGHEÄ THOÂNG TIN GIAÙO TRÌNH THÖÏC HAØNH LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛI Bieân Soaïn: ÑAØO ANH PHA Vónh Long, 05/2006

LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

BOÄ GIAÙO DUÏC VAØ ÑAØO TAÏO TRÖÔØNG ÑAÏI HOÏC DAÂN LAÄP CÖÛU LONG

KHOA COÂNG NGHEÄ THOÂNG TIN

GIAÙO TRÌNH THÖÏC HAØNH LYÙ THUYEÁT ÑOÀ THÒ VAØ

THUAÄT GIAÛI

Bieân Soaïn: ÑAØO ANH PHA

Vónh Long, 05/2006

Page 2: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

MỤC LỤC MỘT SỐ BÀI TOÁN...................................................................................................2 BÀI TOÁN 1.................................................................................................................2 BÀI TOÁN 2.................................................................................................................3 BÀI TOÁN 3.................................................................................................................4 BÀI TOÁN 4.................................................................................................................5 BÀI TOÁN 6.................................................................................................................7 BÀI TOÁN 7.................................................................................................................8 BÀI TOÁN 8.................................................................................................................9 BÀI TOÁN 9...............................................................................................................10 BÀI TOÁN 10.............................................................................................................11 HƯỚNG DẪN CÀI ĐẶT BÀI TOÁN......................................................................12 BÀI TOÁN 1...............................................................................................................12 BÀI TOÁN 2...............................................................................................................17 BÀI TOÁN 3...............................................................................................................20 BÀI TOÁN 4...............................................................................................................22 BÀI TOÁN 5...............................................................................................................25 BÀI TOÁN 6...............................................................................................................32 BÀI TOÁN 7...............................................................................................................35 BÀI TOÁN 8...............................................................................................................38 BÀI TOÁN 9...............................................................................................................43 BÀI TOÁN 10.............................................................................................................48

Biên Soạn: Đào Anh Pha Trang 1

Page 3: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

MỘT SỐ BÀI TOÁN BÀI TOÁN 1

Viết chương trình tìm bậc cao nhất của đỉnh trong đồ thị với đồ thị vô hướng A[i,j] với A[i,j]=1 nếu có đường đi từ i đến j và ngược lại A[i,j] = 0 nếu không có đường đi từ i đến j. Dữ liệu vào: cho trong file Bai1.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100). - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: thông báo kết quả ra màn hình số bậc cao nhất của đỉnh trong đồ thị đã cho. Ví dụ: Bai1.inp Kết quả: 6 Bac cao nhat: 4 0 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 1 0 Bai1.inp Kết quả: 5 Bac cao nhat: 4 0 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 1 1 1 0 Yêu cầu xử lý:

a) Tìm đỉnh có bậc cao nhất. b) Tìm bậc nhỏ nhẩt của đỉnh. c) Tìm đỉnh có bậc nhỏ nhất. d) Tính tổng bậc của đồ thị. e) Đếm số đỉnh bậc chẵn và bậc lẻ.

Ví dụ:

Kết quả: a) Đỉnh 2,5. b) Bậc 2. c) Đỉnh 1,3,4. d) Tổng bậc của đồ thị 14. e) Số đỉnh bậc chẵn 5, số đỉnh bậc lẻ 0.

Biên Soạn: Đào Anh Pha Trang 2

Page 4: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 2

Viết chương trình kiểm tra tính liên thông của một đồ thị vô hướng A[i,j] với A[i,j]=1 nếu có đường đi từ i đến j và ngược lại A[i,j] = 0 nếu không có đường đi từ i đến j. Dữ liệu vào: cho trong file Bai2.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100). - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: thông báo kết quả ra màn hình ”DO THI LIEN THONG” hay “ DO THI KHONG LIEN THONG”. Ví dụ: Bai2.inp Kết quả: 5 DO THI LIEN THONG 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 Bai2.inp Kết quả: 8 DO THI LIEN THONG 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 Bai2.inp Kết quả: 6 DO THI KHONG LIEN THONG 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Biên Soạn: Đào Anh Pha Trang 3

Page 5: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 3

Viết chương trình đếm số thành phần liên thông của đồ thị vô hướng Anxn với: - A[i,j] = 1 nếu có đường đi từ i đến j. - A[i,j] = 0 nếu không có đường đi từ i đến j. - A[i,j] = A[j,i].

Dữ liệu vào: cho trong file Bai2.inp nội dung dữ liệu giống dữ liệu Bài Toán 2. Dữ liệu ra: hiển thị số thành phần liên thông của đồ thị ra màn hình. Ví dụ: Bai3.inp Kết quả: 6 2 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Bai3.inp Kết quả: 5 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0

Bai3.inp Kết quả: 8 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0

Biên Soạn: Đào Anh Pha Trang 4

Page 6: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 4

Có n thành phố biết rằng đường đi giữa hai các thành phố (nếu có) là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận Anxn trong đó:

a. A[i,j] = 1 nếu có đường đi từ thành phố i đến thành phố j. b. A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. c. A[i,j] = A[j,i].

Hãy xác định mọi đường từ thành phố D đến thành phố C (nếu có). Dữ liệu vào: cho trong file Bai4.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: Xuất ra màn hình mọi đường đi từ đỉnh D đến C hay thông báo không tồn tại đường đi từ D đến C. Ví dụ: Bai4.inp Kết quả: 5 1->2->3->4->5 1 5 1->2->4->5 0 1 0 0 1 1->5 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 Bai3.inp Kết quả: 5 1->2->3->4->5 1 5 1->2->5 0 1 0 1 1 1->4->3->2->5 1 0 1 0 1 1->4->5 0 1 0 1 0 1->5 1 0 1 0 1 1 1 0 1 0 Bai4.inp Kết quả: 6 KHONG CO DUONG DI TU 1 DEN 4 1 4 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Biên Soạn: Đào Anh Pha Trang 5

Page 7: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 5 Một lưới giao thông hai chiều giữa n địa điểm được cho bởi ma trận A[i,j] trong đó A[i,j]=1 nếu có đường đi từ i đến j, còn A[i,j] = 0 trong trường hợp ngược lại. Một người đưa thơ cần đi qua tất cả các con đường này để phát thơ, mỗi đường chỉ qua một lần. Hãy xác định một lộ trình của người đưa thơ này (có thể tồn tại nhiều lộ trình khác nhau) hay thông báo không tồn tại đường như vậy. Dữ liệu vào: cho trong file Bai5.inp.

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: In ra màn hình đường đi của người đưa thơ (nếu có). Ví dụ: Bai5.inp Kết quả: 5 1->2->3->4->2->5->4 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 Bai5.inp Kết quả: 5 KHONG TON TAI DUONG DI 0 1 0 0 0 1 0 1 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 0 Bai5.inp Kết quả: 5 2->1->5->4->2->3->4 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0

Biên Soạn: Đào Anh Pha Trang 6

Page 8: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 6

Một người khách du lịch muốn đi thăm n thành phố được đánh số từ 1 đến n, mỗi thành phố người khách chỉ muốn đi qua chúng một lần. Mạng lưới giao thông giữa n thành phố là hai chiều và được cho bởi ma trận A[i,j] trong đó A[i,j] =1 nếu có đường đi giữa thành phố i và thành phố j, A[i,j] = 0 trong trường hợp ngược lại.

Hãy viết chương trình thiết lập cho người khách một lộ trình (có thể tồn tại nhiều lộ trình) hay thông báo không tồn tại lộ trình theo yêu cầu của khách. Dữ liệu vào: cho trong file Bai6.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng 2 ghi đỉnh mà người khách du lịch xuất phát. - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: In ra màn hình đường đi của người khách (nếu có). Ví dụ: Bai6.inp Kết quả: 5 1->2->3->4->5 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 Bai6.inp Kết quả: 6 KHONG TON TAI DUONG DI 1 0 1 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0

Bai6.inp Kết quả: 6 KHONG TON TAI DUONG DI 1 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Biên Soạn: Đào Anh Pha Trang 7

Page 9: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 7

Có n thành phố biết rằng đường đi giữa các thành phố là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận A[i,j] trong đó:

- A[i,j] là độ dài đường đi từ thành phố i đến thành phố j. - A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. - A[i,j] = A[j,i] - A[i,j] nguyên, không âm.

Hãy xác định đường đi ngắn nhất từ thành phố D đến thành phố C. Dữ liệu vào: đồ thị đã liên thông và cho trong file Bai7.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình đường đi ngắn nhất từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được.

Ví dụ:

Bai7.inp Kết quả: 6 DUONG DI NGAN NHAT LA: 5

1 6 1->2->4->6

0 1 2 0 0 0

1 0 2 2 3 0

2 2 0 5 4 0

0 2 5 0 3 2

0 3 4 3 0 4

0 0 0 2 4 0

Bai7.inp Kết quả: 6 DUONG DI NGAN NHAT LA: 8

1 6 1->2->4->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

Biên Soạn: Đào Anh Pha Trang 8

Page 10: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 8

Một công ty cần thay toàn bộ hệ thống dây điện cho n phòng làm việc. Cho biết sơ đồ điện hiện có của n căn phòng này được biều diễn bằng ma trận A[i,j] trong đó:

- A[i,j]=A[j,i] chính là chiều dài dây điện nối liền giữa hai phòng i và j. - A[i,j] = A[j,i] = 0 nếu i không nối liền với j. Hãy lập trình tính độ dài cuả dây dẫn cần sử dụng sao cho cả n phòng điều có

điện và số lượng này là ít nhất. Dữ liệu vào: cho trong file Bai8.inp (đồ thị cho đã liên thông).

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: lưu trong file Bai8.out với nội dung sau: - Dòng đầu lưu độ dài dây dẫn nhỏ nhất - Các dòng còn lại lưu đường đi cần nối điện giữa đỉnh i nối với đỉnh j có

trọng số A[i,j] (i -> j = A[i][j]).

Ví dụ: Bai8.inp Bai8.out 5 0 3 3 2 2 3 0 2 3 2 3 2 0 1 4 2 3 1 0 4 2 2 4 4 0

7 1 -> 4 = 2 4 -> 3 = 1 1 -> 5 = 2 3 -> 2 = 2

Bai8.inp Bai8.out 8 0 2 3 4 0 0 0 0 2 0 3 0 4 0 0 0 3 3 0 7 6 5 2 0 4 0 7 0 0 0 3 0 0 4 6 0 0 4 0 8 0 0 5 0 4 0 1 6 0 0 2 3 0 1 0 5 0 0 0 0 8 6 5 0

20 1 -> 2 = 2 1 -> 3 = 3 3 -> 7 = 2 7 -> 6 = 1 7 -> 4 = 3 2 -> 5 = 4 7 -> 8 = 5

Biên Soạn: Đào Anh Pha Trang 9

Page 11: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 9

Có n thành phố được đánh số từ 1 đến n. Mạng lưới giao thông giữa các thành phố là đường hai chiều. Trên đường đi từ thành phố i đến thành phố j, người ta không được mang quá A[i,j] đơn vị hàng. Nếu không có đường đi từ thành phố i đến thành phố j thì xem như A[i,j] = 0. Cần vận chuyển hàng từ thành phố D đến thành phố C. Hãy thiết lập kế hoạch vận chuyển sao cho khối lượng hàng vận chuyển là nhiều nhất. Dữ liệu vào: đồ thị đã liên thông và cho trong file Bai9.inp với nội dung

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình kế hoạch vận chuyển từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được. Ví dụ: Bai9.inp Kết quả: 6 KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 2 1 6 1->3->4->6 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 Bai9.inp Kết quả: 6 KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 3 1 6 1->3->4->2->5->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

Biên Soạn: Đào Anh Pha Trang 10

Page 12: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 10

Có n thành phố biết rằng đường đi giữa các thành phố là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận A[i,j] trong đó:

- A[i,j] là độ dài đường đi từ thành phố i đến thành phố j. - A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. - A[i,j] = A[j,i]. - A[i,j] nguyên, không âm.

Hãy xác định đường đi dài nhất từ thành phố D đến thành phố C với điều kiện thành phố đã qua không được đi lại. Dữ liệu vào: đồ thị đã liên thông và cho trong file Bai10.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình đường đi dài nhất từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được.

Ví dụ:

Bai10.inp Kết quả: 6 DUONG DI DAI NHAT LA: 16

1 6 1->2->4->3->5->6

0 1 2 0 0 0

1 0 2 2 3 0

2 2 0 5 4 0

0 2 5 0 3 2

0 3 4 3 0 4

0 0 0 2 4 0

Bai10.inp Kết quả: 6 DUONG DI DAI NHAT LA: 25

1 6 1->3->4->2->5->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

Biên Soạn: Đào Anh Pha Trang 11

Page 13: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN CÀI ĐẶT BÀI TOÁN

BÀI TOÁN 1

Viết chương trình tìm bậc cao nhất của đỉnh trong đồ thị với đồ thị vô hướng A[i,j] với A[i,j]=1 nếu có đường đi từ i đến j và ngược lại A[i,j] = 0 nếu không có đường đi từ i đến j. Dữ liệu vào: cho trong file Bai1.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100). - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: thông báo kết quả ra màn hình số bậc cao nhất của đỉnh trong đồ thị đã cho. Ví dụ: Bai1.inp Kết quả: 6 Bac cao nhat: 4 0 1 1 0 0 0 1 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 0 1 0 0 0 0 1 0 Bai1.inp Kết quả: 5 Bac cao nhat: 4 0 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 1 1 1 0 Yêu cầu xử lý:

f) Tìm đỉnh có bậc cao nhất. g) Tìm bậc nhỏ nhẩt của đỉnh. h) Tìm đỉnh có bậc nhỏ nhất. i) Tính tổng bậc của đồ thị. j) Đếm số đỉnh bậc chẵn và bậc lẻ.

Ví dụ:

Kết quả: f) Đỉnh 2,5. g) Bậc 2. h) Đỉnh 1,3,4. i) Tổng bậc của đồ thị 14. Số đỉnh bậc chẵn 5, số đỉnh bậc lẻ 0.

Biên Soạn: Đào Anh Pha Trang 12

Page 14: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN CÀI ĐẶT Tổng số phần tử khác không trên dòng i của ma trận liên kết của đồ thị chính là số bậc của đỉnh i (i=1..n).

Bậc lớn nhất của đỉnh: Tính bậc từng đỉnh của đồ thị, so sánh tìm ra bậc lớn nhất. Đỉnh có bậc lớn nhất: Tính bậc từng đỉnh của đồ thị, so sánh với bậc lớn nhất của đồ thị nếu bằng thì xuất đỉnh có bậc lớn nhất ra màn hình. Bậc nhỏ nhất của đỉnh: Tính bậc từng đỉnh của đồ thị, so sánh tìm ra bậc nhỏ nhất. Đỉnh có bậc nhỏ nhất: Tính bậc từng đỉnh của đồ thị, so sánh với bậc nhỏ nhất của đồ thị nếu bằng thì xuất đỉnh có bậc nhỏ nhất ra màn hình. Tìm đỉnh bậc lẻ và số đỉnh bậc lẻ: Tính bậc từng đỉnh của đồ thị, kiểm tra đỉnh tương ứng có phải là bậc lẻ hay không nếu phải xuất ra màn hình và tăng số đỉnh bậc lẻ lên 1. Tìm đỉnh bậc chẵn và số đỉnh bậc chẵn: tương tự như tìm số đỉnh bậc lẻ. Tổng bậc của đồ thị: Tổng tất cả các phần tử khác không của ma trận liên kết chính là tổng số bậc của đồ thị.

CHƯƠNG TRÌNH MẪU #include <stdio.h> #include <conio.h> #include <iostream.h> #include <values.h> #define TenFile "Bai1.inp" /*Dọc file dữ liệu bài toán*/ void Doc_File(int **A,int &n) { FILE*f = fopen(TenFile,"rb"); fscanf(f,"%d",&n); *A = new int [n]; cout<<"Ma Tran Lien Ket Cua Do Thi"; for(int i =0;i<n;i++) { A[i] = new int [n]; cout<<endl; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<" "<<A[i][j]; } } fclose(f); } /*Bậc lớn nhất của đỉnh*/ int BacLonNhat(int**A,int n) { int max = 0,Bac;

Biên Soạn: Đào Anh Pha Trang 13

Page 15: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac > max) max = Bac; } return max; } /*Bậc nhỏ nhất của đỉnh*/ int BacNhoNhat(int**A,int n){ int min = MAXINT,Bac; for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac < min) min = Bac; } return min; } /*Tổng bậc của đồ thị*/ int TongBac(int**A,int n){ int Tong = 0; for(int i = 0; i<n; i++) for(int j = 0; j<n; j++) if(A[i][j]>0) Tong++; return Tong; } /*Các đỉnh có bậc nhỏ nhất*/ void DinhBacNhoNhat(int**A, int n){ int min = BacNhoNhat(A,n), Bac; for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac == min) cout<<" "<<i+1;

Biên Soạn: Đào Anh Pha Trang 14

Page 16: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

} } /*Các đỉnh có bậc lớn nhất*/ void DinhBacLonNhat(int**A, int n){ int max = BacLonNhat(A,n), Bac; for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac == max) cout<<" "<<i+1; } } /*Các đỉnh bậc chẵn và số đỉnh bậc chẵn*/ void DinhBacChan(int**A, int n) { int Bac,Tong=0; for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac%2==0) { cout<<" "<<i+1; Tong++; } } cout<<"\n\t So Dinh Bac Chan: "<<Tong; } /*Các đỉnh bậc lẻ và số đỉnh bậc lẻ*/ void DinhBacLe(int**A, int n){ int Bac,Tong=0; for(int i = 0; i<n; i++) { Bac = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) Bac++; if(Bac%2==1) { cout<<" "<<i+1; Tong++; } }

Biên Soạn: Đào Anh Pha Trang 15

Page 17: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

cout<<"\n\t So Dinh Bac Le: "<<Tong; } /*Chuong Trinh Chinh*/ void main() { clrscr(); int **A,n; Doc_File(A,n); cout<<"\n1. Bac Lon Nhat Cua Dinh: "<<BacLonNhat(A,n); cout<<"\n2. Dinh Co Bac Lon Nhat:"; DinhBacLonNhat(A,n); cout<<"\n3. Bac Nho Nhat Cua Dinh: "<<BacNhoNhat(A,n); cout<<"\n4. Dinh Co Bac Nho Nhat:"; DinhBacNhoNhat(A,n); cout<<"\n5. Dinh Co Bac Chan:"; DinhBacChan(A,n); cout<<"\n6. Dinh Co Bac Le:"; DinhBacLe(A,n); cout<<"\n7. Tong Bac Cua Do Thi: "<<TongBac(A,n); delete*A; getch(); }

Biên Soạn: Đào Anh Pha Trang 16

Page 18: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 2

Viết chương trình kiểm tra tính liên thông của một đồ thị vô hướng A[i,j] với A[i,j]=1 nếu có đường đi từ i đến j và ngược lại A[i,j] = 0 nếu không có đường đi từ i đến j. Dữ liệu vào: cho trong file Bai2.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100). - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: thông báo kết quả ra màn hình ”DO THI LIEN THONG” hay “ DO THI KHONG LIEN THONG”. Ví dụ: Bai2.inp Kết quả: 5 DO THI LIEN THONG 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 Bai2.inp Kết quả: 8 DO THI LIEN THONG 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 Bai2.inp Kết quả: 6 DO THI KHONG LIEN THONG 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Biên Soạn: Đào Anh Pha Trang 17

Page 19: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN THUẬT TOÁN Ý tưởng: Sử dụng thuật toán loang . Bước 1: Xuất phát từ một đỉnh bất kỳ của đồ thị. Ta đánh dấu đỉnh xuất phát và chuyển sang bước 2. Bước 2: Từ một đỉnh i đã đánh dấu, ta đánh dấu đỉnh j nếu A[i,j] = 1 và j chưa được đánh dấu và chuyển sang bước 3. Bước 3: Thực hiện bước 2 cho đến khi không còn thực hiện được nữa chuyển sang bước 4. Bước 4: Kiểm tra nếu số đỉnh đánh dấu nhỏ hơn n (hay tồn tại ít nhất một đỉnh chưa được đánh dấu) đồ thị sẽ không liên thông và ngược lại đồ thị liên thông.

HƯỚNG DẪN CÀI ĐẶT Tổ chức cấu trúc dữ liệu để lưu trữ sự đánh dấu các đỉnh của đồ thị.

Ta tổ chức một mảng 1 chiều (char*DanhDau) để lưu trữ những đỉnh của đồ thị có được đánh dấu hay không. Chỉ số của mảng chính là chỉ số đỉnh của đồ thị.

DanhDau[i]=0 nếu đỉnh i chưa được đánh dấu và DanhDau[i]=1 nếu đỉnh i đã được đánh dấu. Ví dụ: DanhDau[5]=1, DanhDau[3]=0 có nghĩa là đỉnh thứ 5 của đồ thị đã được dánh đấu và đỉnh thứ 3 của đồ thị chưa được dánh dấu.

Trong thuật toán, trước tiên ta khởi tạo tất cả các đỉnh của đồ thị là chưa được đánh dấu. Nghĩa là DanhDau[i]=0, i=0..n-1.

o Dánh dấu đỉnh dầu tiên của đồ thị (DanhDau[0]=1). o Từ đỉnh i đã đánh dấu (DanhDau[i]=1), ta đánh dấu đỉnh j (DanhDau[j]=1)

nếu A[i][j] = 1 và j chưa được đánh dấu (DanhDau[j]=0). Cứ tiếp tục như vậy cho đến khi không thực hiện được nữa.

o Nếu đỉnh nào chưa đánh dấu (tồn tại DanhDau[k]=0, 0≤k<n) thì đồ thị không liên thông và ngược lại.

CHƯƠNG TRÌNH MẪU #include <stdio.h> #include <conio.h> #include <iostream.h> #define TenFile "Bai2.inp" /*Dọc file dữ liệu*/ void Doc_File(int **A,int &n){ FILE*f = fopen(TenFile,"rb"); fscanf(f,"%d",&n); *A = new int [n]; cout<<"Ma Tran Lien Ket Cua Do Thi"; for(int i =0;i<n;i++) { A[i] = new int [n]; cout<<endl;

Biên Soạn: Đào Anh Pha Trang 18

Page 20: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<" "<<A[i][j]; } } fclose(f); } /*Kiểm tra liên thông: Nếu liên thông trả về giá trị 1, ngược lại trả về giá trị 0*/ char Lien_Thong(int **A,int n) { char*DanhDau = new char [n]; char ThanhCong; int Dem=0; for(int i = 0; i<n; i++) DanhDau[i] = 0; DanhDau[0] = 1; Dem++; do { ThanhCong =1; for(i = 0; i<n; i++) if(DanhDau[i]==1) { for(int j = 0; j<n; j++) if (DanhDau[j] == 0 && A[i][j] > 0) { DanhDau[j] = 1; ThanhCong =0; Dem++; if(Dem == n) return 1; } } }while (ThanhCong == 0); return 0; } /*Chương trình chính*/ void main() { clrscr(); int **A,n; Doc_File(A,n); if (Lien_Thong(A,n)==1) cout<<"\nDO THI LIEN THONG"; else cout<<"\nDO THI KHONG LIEN THONG"; delete *A; getch(); }

Biên Soạn: Đào Anh Pha Trang 19

Page 21: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 3

Viết chương trình đếm số thành phần liên thông của đồ thị vô hướng Anxn với: - A[i,j] = 1 nếu có đường đi từ i đến j. - A[i,j] = 0 nếu không có đường đi từ i đến j. - A[i,j] = A[j,i].

Dữ liệu vào: cho trong file Bai2.inp nội dung dữ liệu giống dữ liệu Bài Tập2. Dữ liệu ra: hiển thị số thành phần liên thông của đồ thị ra màn hình. Ví dụ: Bai3.inp Kết quả: 6 2 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Bai3.inp Kết quả: 5 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0

Bai3.inp Kết quả: 8 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0

HƯỚNG DẪN THUẬT TOÁN Ý tưởng: Sử dụng thuật toán loang giống như bài toán 1. Bước 0: Khởi tạo số thành phần liên thông bằng 0. Bước 1: Xuất phát từ một đỉnh chưa được đánh dấu của đồ thị. Ta đánh dấu đỉnh xuất phát, tăng số thành phần liên thông lên 1 và chuyển sang bước 2. Bước 2: Từ một đỉnh i đã đánh dấu, ta đánh dấu đỉnh j nếu A[i,j] = 1 và j chưa được đánh dấu và chuyển sang bước 3.

Biên Soạn: Đào Anh Pha Trang 20

Page 22: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

Bước 3: Thực hiện bước 2 cho đến khi không còn thực hiện được nữa chuyển sang bước 4. Bước 4: Nếu số số đỉnh đánh dấu bằng n (mọi đỉnh đều được đánh dấu) kết thúc thuật toán, ngược lại quay về bước 1. Chú ý: Nếu số thành phần liên thông bằng 1 đồ thị liên thông.

HƯỚNG DẪN CÀI ĐẶT Cài đặt tương tự như bài toán 2. CHƯƠNG TRÌNH MẪU /*Hàm trả về số thành phần liên thông của đồ thị vô hướng */ int TPLien_Thong(int **A, int n) { char*DanhDau = new char [n]; char ThanhCong; int Dem=0, i,j, MLT=0; for( i = 0; i<n; i++) DanhDau[i] = 0; do { j = 0; while(DanhDau[j]==1) j++; DanhDau[j] = 1; Dem++; MLT++; do { ThanhCong =0; for(i = 0; i<n; i++) if(DanhDau[i]==1) for(j = 0; j<n; j++) if (DanhDau[j] == 0 && A[i][j] > 0) { DanhDau[j] = 1; ThanhCong =1; Dem++; if(Dem == n) return MLT; } }while (ThanhCong == 1); } while(Dem<n); return MLT; }

Biên Soạn: Đào Anh Pha Trang 21

Page 23: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 4

Có n thành phố biết rằng đường đi giữa hai các thành phố (nếu có) là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận Anxn trong đó:

d. A[i,j] = 1 nếu có đường đi từ thành phố i đến thành phố j. e. A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. f. A[i,j] = A[j,i].

Hãy xác định mọi đường từ thành phố D đến thành phố C (nếu có). Dữ liệu vào: đồ thị liên thông và cho trong file Bai4.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: Xuất ra màn hình mọi đường đi từ đỉnh D đến C hay thông báo không tồn tại đường đi từ D đến C. Ví dụ: Bai4.inp Kết quả: 5 1->2->3->4->5 1 5 1->2->4->5 0 1 0 0 1 1->5 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 Bai3.inp Kết quả: 5 1->2->3->4->5 1 5 1->2->5 0 1 0 1 1 1->4->3->2->5 1 0 1 0 1 1->4->5 0 1 0 1 0 1->5 1 0 1 0 1 1 1 0 1 0 Bai4.inp Kết quả: 6 KHONG CO DUONG DI TU 1 DEN 4 1 4 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

Biên Soạn: Đào Anh Pha Trang 22

Page 24: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN THUẬT TOÁN Sử dụng kỹ thuật tìm kiếm theo chiều sâu.

HƯỚNG DẪN CÀI ĐẶT Sử dụng kỹ thuật cài đặt tìm kiếm theo phương pháp đệ quy.

CHƯƠNG TRÌNH MẪU #include <stdio.h> #include <conio.h> #include <iostream.h> #define FileIn "Bai4.inp" int Dem = 0; //Dếm số đường đi int*L; //Lưu lại đường đã đi char*DanhDau; //Đánh dấu đỉnh đã đi int **A,n,D,C; /*Dọc file dữ liệu theo yêu cầu của chương trình*/ void Doc_File(){ FILE*f = fopen(FileIn,"rb"); fscanf(f,"%d%d%d",&n,&D,&C); cout<<"Ma Tran Lien Ket Tuong Ung.\n"; cout<<D<<" "<<C<<endl; *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<A[i][j]<<" "; } cout<<endl; } fclose(f); D--; C--; } /*Khởi tạo các tham số ban đầu cho chương trình*/ void KhoiTao() { DanhDau = new char [n]; L = new int [n]; for (int i = 0; i<n; i++) { //Tất cả các đỉnh chưa được đánh dấu DanhDau[i] = 0; L[i] = 0; }

Biên Soạn: Đào Anh Pha Trang 23

Page 25: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

DanhDau[D] = 1; //Đánh dấu đỉnh đầu tiên L[0] = D; //Lưu lại đỉnh đầu tiên là đỉnh xuất phát } void InDuongDi(int SoCanh) { Dem++; cout<<endl<<D+1; for (int i = 1; i<SoCanh; i++) cout<<" -> "<<L[i]+1; } /*Thủ tục đệ quy tìm kiếm đường đi*/ void TimKiem(int SoCanh) { if(L[SoCanh-1] == C) InDuongDi(SoCanh); else { for(int i = 0; i<n; i++) if( A[L[SoCanh-1]][i]>0 && DanhDau[i] == 0){ L[SoCanh] = i; DanhDau[i] = 1; TimKiem(SoCanh+1); //Tìm kiếm đỉnh tiếp theo L[SoCanh] = 0; DanhDau[i] = 0; } } } /*Chương trình chính*/ void main() { clrscr(); Doc_File(); KhoiTao(); cout<<"Duong di tu "<<D+1<<" den "<<C+1; TimKiem(1); if(Dem==0) cout<<" khong co"; delete*A,DanhDau,L; getch(); }

Biên Soạn: Đào Anh Pha Trang 24

Page 26: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 5

Một lưới giao thông hai chiều giữa n địa điểm được cho bởi ma trận A[i,j] trong đó A[i,j]=1 nếu có đường đi từ i đến j, còn A[i,j] = 0 trong trường hợp ngược lại. Một người đưa thơ cần đi qua tất cả các con đường này để phát thơ, mỗi đường chỉ qua một lần. Hãy xác định một lộ trình của người đưa thơ này (có thể tồn tại nhiều lộ trình khác nhau) hay thông báo không tồn tại đường như vậy. Dữ liệu vào: cho trong file Bai5.inp.

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: In ra màn hình đường đi của người đưa thơ (nếu có). Ví dụ: Bai5.inp Kết quả: 5 1->2->3->4->2->5->4 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 Bai5.inp Kết quả: 5 KHONG TON TAI DUONG DI 0 1 0 0 0 1 0 1 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 0 Bai5.inp Kết quả: 5 2->1->5->4->2->3->4 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 HƯỚNG DẪN THUẬT TOÁN Bài toán 5 chính là bài toán tìm đường đi Euler. Điều kiện để có đường đi Euler là:

- Đồ thị liên thông. - Đồ thị có không quá 2 đỉnh bậc lẻ. Nếu có 2 đỉnh bậc lẻ thì đỉnh xuất phát

tìm đường đi phải là đỉnh bậc lẻ.

Biên Soạn: Đào Anh Pha Trang 25

Page 27: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

Ý tưởng thuật toán: Sử dụng kỹ thuật xoá cạnh. Nghĩa là, khi ta đi qua bất kỳ cạnh nào ta phải xoá cạnh tương ứng bằng cách gán trọng số đường đi của cạnh mới đi qua bằng 0. Thuật toán kết thúc khi ta đi qua tất cả các cạnh của đồ thị khi đó ma trận trận liên kết của đồ thị bằng 0.

HƯỚNG DẪN CÀI ĐẶT Cài đặt hàm kiểm tra tính liên thông của đồ thị nếu liên thông trả về kết quả 1

ngược lại trả về kết quả 0. Cài đặt hàm kiểm tra đồ thị có thỏa mãn tồn tại không quá 2 đỉnh bậc lẻ nếu

thỏa mãn trả về kết quả 1 ngược lại trả về kết quả 0. Nếu tồn tại đỉnh bậc lẻ thì đỉnh bậc lẻ chính là đỉnh xuất phát và trong quá trình kiểm tra chúng ta đếm luôn số cạnh của đồ thị. Bởi vì thuật toán kết thúc khi ta đi hết tất cả mọi cảnh của đồ thị.

Cài đặt thuật toán tìm đường đi Euler: trước tiên kiểm tra xem đồ thị co thỏa mãn điều kiện tồn tại đường đi Euler hay chưa nếu không thỏa mãn thì thuật toán kết thúc. Ngược lại ta tìm đường đi Euler như sau: - Chọn đỉnh xuất phát: nếu tồn tại đỉnh bậc lẻ thì chọn đỉnh bậc lẻ làm đỉnh

xuất phát, nếu không tồn tại đỉnh bậc lẻ thì chọn 1 đỉnh bất kỳ thông thường ta chọn đỉnh 1 làm đỉnh xuất phát.

- Từ đỉnh xuất phát ta đi tới đỉnh kề nó và xóa cạnh tương ứng. Nếu j là đỉnh kề với đỉnh xuất phát thì A[xuất phát][j]= A[j][xuất phát] = 0 và đỉnh xuất phát ta gán bằng đỉnh j. Lặp lại cho đến khi không còn đi được nữa (đi qua mọi cạnh của đồ thị) thì thuật toán kết thúc.

CHƯƠNG TRÌNH MẪU

#include <stdio.h> #include <conio.h> #include <iostream.h> #include <values.h> #define TenFile "Bai5.inp" /*Dọc dữ liệu của bài toán*/ void Doc_File(int **A,int &n) { FILE*f = fopen(TenFile,"rb"); fscanf(f,"%d",&n); *A = new int [n]; cout<<"Ma Tran Lien Ket Cua Do Thi"; for(int i =0;i<n;i++) { A[i] = new int [n]; cout<<endl; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]);

Biên Soạn: Đào Anh Pha Trang 26

Page 28: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

cout<<" "<<A[i][j]; } } fclose(f); } /*Kiểm tra tính liên thông của đồ thị. Đồ thị liên thông thì hàm trả về giá trị 1, ngược lại hàm trả về giá trị 0.*/ char LienThong(int **A,int n) { char*DanhDau = new char [n]; char ThanhCong; int Dem=0; for(int i = 0; i<n; i++) DanhDau[i] = 0; DanhDau[0] = 1; Dem++; do { ThanhCong =1; for(i = 0; i<n; i++) if(DanhDau[i]==1) { for(int j = 0; j<n; j++) if (DanhDau[j] == 0 && A[i][j] > 0) { DanhDau[j] = 1; ThanhCong =0; Dem++; if(Dem == n) return 1; } } }while (ThanhCong == 0); return 0; } /*Kiểm tra đồ thị có quá 2 đỉnh bậc lẻ hay không. Nếu quá 2 đỉnh bậc lẻ hàm trả về giá trị 0, ngược lại hàm trả về giá trị 1. Tìm đỉnh xuất phát lưu trong biến XP và tổng số cạnh lưu trong biến Canh*/ char KiemTraBacLe(int**A, int n,int &XP, int &Canh) { int BacDinh,BacLe=0; Canh = 0; XP = 0; for(int i = n-1; i>=0; i--) { BacDinh = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) BacDinh++;

Biên Soạn: Đào Anh Pha Trang 27

Page 29: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

if(BacDinh%2==1) { XP= i; BacLe++; } Canh+=BacDinh; } Canh = Canh/2; if(BacLe>2) return 0; else return 1; } /*Tim mot duong di Euler*/ void Euler(int**A,int n){ int XuatPhat,SoCanh,Dem; int *LuuDuong; if(LienThong(A,n)==1 && KiemTraBacLe(A,n,XuatPhat,SoCanh)==1){ LuuDuong = new int[SoCanh+1]; LuuDuong[0] = XuatPhat; Dem = 1; do{ int j = 0; while(A[XuatPhat][j]==0) j++; A[XuatPhat][j] = A[j][XuatPhat] = 0; LuuDuong[Dem] = XuatPhat = j; Dem++; }while(Dem<=SoCanh); cout<<"\nDuong Di Cua Nguoi Dua Tho:\n"<<LuuDuong[0]+1; for(int i = 1; i<=SoCanh; i++) cout<<" -> "<<LuuDuong[i]+1; }else cout<<"\nKhong ton tai duong di."; } /*Chương trình chính*/ void main() { clrscr(); int **A,n; Doc_File(A,n); Euler(A,n); delete*A; getch(); }

Biên Soạn: Đào Anh Pha Trang 28

Page 30: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

CẢI TIẾN THUẬT TOÁN XỬ LÝ CÁC TRƯỜNG HỢP ĐẶC BIỆT 1. Trường hợp đồ thị có 2 đỉnh bậc lẻ trong đó có 1đỉnh bậc 1.

Xét đồ thị:

Nếu chúng ta xuất phát từ đỉnh 4. Khi chúng ta đi 4->2->1 đồ thị của ta sẽ tương ứng với thuật toán xoá cạnh là:

Khi đó điểm xuất phát của ta sẽ bắt đầu từ đỉnh 1, tại đỉnh này chúng ta sẽ không còn đường đi nữa vì nó là đỉnh cô lập. Để khắc phục được hiện trạng này chúng ta phải chọn ưu tiên đỉnh xuất phát là đỉnh có bậc 1 và đỉnh kết thúc sẽ là đỉnh bậc lẻ còn lại. Bai5.inp Kết quả: 6 4->2->5->1->3->5->6->2 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0

Hàm cải tiến kiểm tra đỉnh bậc lẻ và chon đỉnh xuất phát. char KiemTraBacLe(int**A, int n,int &XP, int &Canh) { int BacDinh,BacLe=0,T=0; Canh = XP = 0; for(int i = 0; i<n; i++) { BacDinh = 0; for(int j = 0; j<n; j++) if(A[i][j]>0) BacDinh++; if(BacDinh%2==1) { if(BacDinh==1) { T = 1; XP= i; }

Biên Soạn: Đào Anh Pha Trang 29

Page 31: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

if(T = 0) XP = i; BacLe++; } Canh+=BacDinh; } Canh = Canh/2; if(BacLe>2) return 0; else return 1; }

2. Trường hợp đồ thị có 2 đỉnh bậc lẻ trong đó có 2 đỉnh bậc 1. Xử lý tương tự như trường hợp 1 nhưng ta phải lưu vết đường đi đã đi qua để tránh trường hợp đường đi sau khi xóa thì đỉnh tương ứng xuất phát là đỉnh cô lập. Có nhiều cách để lưu vết, tìm kiếm bằng phương pháp đệ quy là một trong những cánh lưu vết hiệu quả và đơn giản. Tuy nhiên đồ phức tạp của thuật toán quá lớn nên trong thực tế người ta ích sử dụng phương pháp này.

3. Kỹ thuật tìm kiếm đệ quy tìm đường đi Euler.

#include <stdio.h> #include <conio.h> #include <iostream.h> #define Filename "Bai5.inp" /*Khai báo các biến toàn cục*/ int Dem = 0; //Đếm số đường đi int*L; //Lưu lại đỉnh đã đi int **A,n int XuatPhat=0; //Đỉnh xuẩt phát tìm kiếm là đỉnh bậc lẻ nếu đồ thị có đỉnh bậc lẻ int SoCanh=0; //Lưu số cạnh của đồ thị vì đường đi đi qua tất cả các cạnh /*Dọc file dữ liệu và khởi tạo ban đầu*/ void Doc_File(){ int BacDinh; FILE*f = fopen(Filename,"rb"); fscanf(f,"%d",&n); cout<<"Ma Tran Lien Ket Tuong Ung.\n"<<n<<endl; *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; BacDinh = 0; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<A[i][j]<<" ";

Biên Soạn: Đào Anh Pha Trang 30

Page 32: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

if(A[i][j] == 1) BacDinh++; } if(BacDinh%2==1) XuatPhat = i; //Xuẩt phát là đỉnh bậc lẻ SoCanh+=BacDinh; cout<<endl; } fclose(f); SoCanh = SoCanh/2; //Số cạnh = tổng bậc /2 L = new int [SoCanh+1]; //Khởi tạo lưu đỉnh L[0] = XuatPhat; } /*Xuất đường đi tìm được ra màn hình*/ void InDuongDi() { Dem++; cout<<endl<<XuatPhat+1; for (int i = 1; i<=SoCanh; i++) cout<<" -> "<<L[i]+1; } /*Thủ tục tìm kiếm đệ quy*/ void TimKiem(int Canh) { /*Tìm cho đến khi cạnh tìm được lớn hơn số cạnh của đồ thị mới xuất đường đi*/ if(Canh > SoCanh && Dem ==0 ) InDuongDi(); else { for(int i = 0; i<n; i++) if( A[L[Canh-1]][i]>0 && Dem==0){ L[Canh] = i; A[L[Canh-1]][i]=A[i][L[Canh-1]]=0; //Xóa cạnh TimKiem(Canh+1); //Tìm đỉnh tiếp theo A[L[Canh-1]][i]=A[i][L[Canh-1]]=1; //Phục hồi cạnh L[Canh] = 0; } } } void main() { Doc_File(); cout<<"\nDUONG DI"; TimKiem(1); if(Dem==0) cout<<" KHONG CO"; delete*A,L; getch(); }

Biên Soạn: Đào Anh Pha Trang 31

Page 33: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 6

Một người khách du lịch muốn đi thăm n thành phố được đánh số từ 1 đến n, mỗi thành phố người khách chỉ muốn đi qua chúng một lần. Mạng lưới giao thông giữa n thành phố là hai chiều và được cho bởi ma trận A[i,j] trong đó A[i,j] =1 nếu có đường đi giữa thành phố i và thành phố j, A[i,j] = 0 trong trường hợp ngược lại.

Hãy viết chương trình thiết lập cho người khách một lộ trình (có thể tồn tại nhiều lộ trình) hay thông báo không tồn tại lộ trình theo yêu cầu của khách. Dữ liệu vào: cho trong file Bai6.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng 2 ghi đỉnh mà người khách du lịch xuất phát. - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: In ra màn hình đường đi của người khách (nếu có). Ví dụ: Bai6.inp Kết quả: 5 1->2->3->4->5 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 0 Bai6.inp Kết quả: 6 KHONG TON TAI DUONG DI 1 0 1 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 Bai6.inp Kết quả: 5 2->1->5->4->3 2 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1 0

Biên Soạn: Đào Anh Pha Trang 32

Page 34: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

Bai6.inp Kết quả: 6 KHONG TON TAI DUONG DI 1 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

HƯỚNG DẪN THUẬT TOÁN Sử dụng kỹ thuật tìm kiếm theo chiều sâu.

HƯỚNG DẪN CÀI ĐẶT Sử dụng kỹ thuật cài đặt tìm kiếm theo phương pháp đệ quy. CHƯƠNG TRÌNH MẪU

#include <stdio.h> #include <conio.h> #include <iostream.h> #define FileIn "Bai6.inp" int Dem = 0; //Dếm số đường đi int*L; //Lưu lại đường đi char*DanhDau; //Dánh dấu đỉnh đã đi int **A,n,D; /*Dọc file dữ liệu bài toán*/ void Doc_File() { FILE*f = fopen(FileIn,"rb"); fscanf(f,"%d%d",&n,&D); cout<<"Ma Tran Lien Ket Tuong Ung.\n"<<D<<endl; *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<A[i][j]<<" "; } cout<<endl; } fclose(f); D--; } /*Khởi tạo dữ liệu ban đầu cho bài toán*/ void KhoiTao() {

Biên Soạn: Đào Anh Pha Trang 33

Page 35: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

DanhDau = new char [n]; L = new int [n]; for (int i = 0; i<n; i++) { DanhDau[i] = 0; L[i] = 0; } DanhDau[D] = 1; L[0] = D; } /*In đường đi của bài toán ra màn hình*/ void InDuongDi(int Dinh) { Dem++; cout<<endl<<D+1; for (int i = 1; i<Dinh; i++) cout<<" -> "<<L[i]+1; } /*Tìm kiếm đường đi*/ void TimKiem(int Dinh) { if(Dinh == n && Dem == 0) InDuongDi(Dinh); else { for(int i = 0; i<n; i++) if( A[L[Dinh-1]][i]>0 && DanhDau[i] == 0 && Dem==0){ L[Dinh] = i; DanhDau[i] = 1; TimKiem(Dinh+1); //Tiếm kiếm đỉnh kế tiếp L[Dinh] = 0; DanhDau[i] = 0; } } } /*Chương trình chính*/ void main() { clrscr(); Doc_File(); KhoiTao(); cout<<"Duong Di Nguoi Khach"; TimKiem(1); //Tìm kiếm từ đỉnh thứ 2 của đồ thị if(Dem==0) cout<<" Khong Co"; delete*A,DanhDau,L; getch(); }

Biên Soạn: Đào Anh Pha Trang 34

Page 36: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 7

Có n thành phố biết rằng đường đi giữa các thành phố (nếu có) là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận A[i,j] trong đó:

- A[i,j] là độ dài đường đi từ thành phố i đến thành phố j. - A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. - A[i,j] = A[j,i] - A[i,j] nguyên, không âm.

Hãy xác định đường đi ngắn nhất từ thành phố D đến thành phố C. Dữ liệu vào: đồ thị đã liên thông và cho trong file Bai7.inp với nội dung

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình đường đi ngắn nhất từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được. Ví dụ: Bai7.inp Kết quả: 6 DUONG DI NGAN NHAT LA: 5 1 6 1->2->4->6 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 Bai7.inp Kết quả: 6 DUONG DI NGAN NHAT LA: 8

1 6 1->2->4->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

HƯỚNG DẪN THUẬT TOÁN Sử dụng thuật toán DIJKSTRA tìm đường đi ngắn nhất.

Biên Soạn: Đào Anh Pha Trang 35

Page 37: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

CHƯƠNG TRÌNH MẪU

#include <stdio.h>

#include <conio.h>

#include <iostream.h>

#include <values.h>

#define FileIn "Bai7.inp"

/*Đọc file dữ liệu bài toán*/

void Doc_File(int**A, int &n, int &D, int &C){

FILE*f = fopen(FileIn,"rb");

fscanf(f,"%d%d%d",&n,&D,&C);

cout<<"Ma Tran Lien Ket Tuong Ung.\n"<<D<<" "<<C<<endl;

*A = new int [n];

for(int i =0;i<n;i++) {

A[i] = new int [n];

for(int j =0;j<n;j++) {

fscanf(f,"%d",&A[i][j]);

cout<<A[i][j]<<" ";

}

cout<<endl;

}

fclose(f);

D--; C--;

}

/*Thuật toán Dijkstra tìm đường đi ngắn nhẩt từ đỉnh D đến đỉnh C*/

void Dijkstra(int **A, int n, int D, int C) {

char *DanhDau = new char[n];

int *Nhan = new int[n];

int *Truoc = new int[n];

int XP, min;

for(int i=0; i<n; i++){

Nhan[i] = MAXINT;

DanhDau[i] = 0;

Truoc[i] = D;

}

Biên Soạn: Đào Anh Pha Trang 36

Page 38: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

Nhan[D] = 0;

DanhDau[D] = 1;

XP = D;

while(XP != C){

for(int j=0; j<n; j++)

if(A[XP][j]>0 && Nhan[j]>A[XP][j]+Nhan[XP] && DanhDau[j]==0) {

Nhan[j] = A[XP][j]+Nhan[XP];

Truoc[j] = XP;

}

min = MAXINT;

for(j = 0; j<n; j++)

if(min>Nhan[j]&& DanhDau[j]==0){

min = Nhan[j] ;

XP = j ;

}

DanhDau[XP] = 1;

}

cout<<”Duong Di Ngan Nhat La:”<<Nhan[C]<<endl;

cout<<C+1<<” <- “<<Truoc[C]+1;

i = Truoc[C];

while(i!=D){

i = Truoc[i];

cout<<” <- “<<i+1;

}

}

/*Chương trình chính*/

void main() {

int**A,n,Dau,Cuoi;

Doc_File(A,n,Dau,Cuoi);

Dijkstra(A,n,Dau,Cuoi);

delete*A;

getch();

}

Biên Soạn: Đào Anh Pha Trang 37

Page 39: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 8

Một công ty cần thay toàn bộ hệ thống dây điện cho n phòng làm việc. Cho biết sơ đồ điện hiện có của n căn phòng này được biều diễn bằng ma trận A[i,j] trong đó:

- A[i,j]=A[j,i] chính là chiều dài dây điện nối liền giữa hai phòng i và j. - A[i,j] = A[j,i] = 0 nếu i không nối liền với j. Hãy lập trình tính độ dài cuả dây dẫn cần sử dụng sao cho cả n phòng điều có

điện và số lượng này là ít nhất. Chú ý: đồ thị đã cho là liên thông. Dữ liệu vào: cho trong file Bai8.inp (đồ thị cho đã liên thông).

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng i+1 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: lưu trong file Bai8.out với nội dung sau: - Dòng đầu lưu độ dài dây dẫn nhỏ nhất - Các dòng còn lại lưu đường đi cần nối điện giữa đỉnh i nối với đỉnh j có

trọng số A[i,j] (i -> j = A[i][j]).

Bai8.inp Bai8.out 5 0 3 3 2 2 3 0 2 3 8 3 2 0 1 4 2 3 1 0 4 2 8 4 4 0

7 4 – 3 3 – 2 4 – 1 1 – 5

Bai8.inp Bai8.out 8 0 2 3 4 0 0 0 0 2 0 3 0 4 0 0 0 3 3 0 7 6 5 2 0 4 0 7 0 0 0 3 0 0 4 6 0 0 4 0 8 0 0 5 0 4 0 1 6 0 0 2 3 0 1 0 5 0 0 0 0 8 6 5 0

20 1 - 2 1 - 3 3 - 7 7 - 6 7 - 4 2 - 5 7 - 8

HƯỚNG DẪN THUẬT TOÁN

Thuật toán Prim tìm cây phủ tối tiểu. Thuật toán Kruskal tìm cây phủ tối tiểu.

1) Thuật toán Prim tìm cây phủ tối tiểu. Bước 1: Xuất phát từ đỉnh k bất kỳ (thông thường chon k là đỉnh đầu tiên) chọn một cạnh có trọng số nhỏ nhất của đồ thị (min{A[k][j]}j=1..n) ta đánh dấu 2 đỉnh đi qua cạnh

Biên Soạn: Đào Anh Pha Trang 38

Page 40: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

đó và số cạnh tìm được là 1. Chuyển sang bước 2. Bước 2: Tìm cạnh nhỏ nhất của đồ thị với điều kiện cạnh tìm được phải có 1 đỉnh chưa đánh dấu và 1 đỉnh đã đánh dấu (min{A[i][j]}j=1..n, i=1..n sao cho i đánh đấu và j chưa đánh dấu) để tránh trường hợp tạo thành chu trình. Ta tăng số cạnh tìm được lên 1 và chuyển sang bước 3. Bước 3: Nếu số cạnh tìm được bằng n-1 kết thúc thuật toán, ngược lại quay về bước 2.

2) Thuật toán Kruskal tìm cây phủ tối tiểu. Bước 0: Khởi tạo tập cạnh tìm được là rỗng. Chuyển sang bước 1. Bước 1: Chọn một cạnh có trọng số nhỏ nhất sao cho khi đưa cạnh này vào tập cạnh tìm được không tạo thành chu trình. Tăng số cạnh tìm được lên 1và chuyển sang bước 2. Bước 2: Nếu số cạnh tìm được bằng n-1 thuật toán kết thúc, ngược lại quay về bước 1.

HƯỚNG DẪN CÀI ĐẶT 1) Thuật toán Prim tìm cây phủ tối tiểu. Ta tổ chức mảng 1 chiều D để đánh dấu . Nếu D[i]=1 đỉnh i được đánh dấu và D[i]=0 nếu i chưa được đánh dấu. Bước 1: Tìm min{A[i][j]}j=1..n, i=1..n. Sau đó gán D[i]=D[j]=1 (đánh dấu 2 đỉnh i,j) và cho số cạnh tìm được bằng 1 (Dem=1). Bước 2: Tìm min{A[i][j]}j=1..n, i=1..n với điều kiện D[i]=1 và D[j]=0. Sau đó gán D[j]=1 (đánh dấu đỉnh j vừa tìm được) và tăng số cạnh lên 1 (Dem++). Bước 3: Nếu Dem = n-1 thì thuật toán kết thúc.

2) Thuật toán Kruskal tìm cây phủ tối tiểu. Ta tổ chức mảng 1 chiều D để đánh dấu . Nếu D[i]=T thì đỉnh i thuộc vào cây thứ

T, D[i] = 0 thì đỉnh i chưa thuộc vào cây. Bước 1: Tìm min{A[i][j]}j=1..n, i=1..n ngoại trừ điều kiện D[i]=D[j]≠0. Vì khi thỏa mãn điều kiện trên đỉnh i,j đã thuộc vào một cây do đó khi lấy thêm cạnh này chúng sẽ tạo thành chu trình. Đỉnh i,j tìm được thoả mãn một trong các trường hợp sau:

- Nếu D[i]=D[j]=0, đỉnh i,j chưa thuộc vào cây nên khi lấy 2 đỉnh này vào tập cạnh ta cho chúng thuộc vào 1 cây mới. Nghĩa là số cây T++ và D[i]=D[j]=T.

- Nếu D[i]=0 và D[j]≠0, đỉnh i chưa thuộc vào cây và j đã thuộc vào cây. Ta lấy đỉnh i vào cây tương ứng với cây của đỉnh j. Nghĩa là gán D[i]=D[j].

- Nếu D[i]≠0 và D[j]=0, đỉnh j chưa thuộc vào cây và i đã thuộc vào cây. Ta lấy đỉnh j vào cây tương ứng với cây của đỉnh i. Nghĩa là gán D[j]=D[i].

- Nếu D[i]≠D[j] và D[i]≠0 và D[j]≠0, đỉnh i thuộc vào cây và đỉnh j cũng thuộc vào cây nhưng cây i và j là 2 cây khác nhau. Ta tiến hành ghép cây nghĩa là ghép 2 cây chứa i,j thành 1 cây mới.

Temp = D[i] for(int i=0 ; i<n ; i++)

Biên Soạn: Đào Anh Pha Trang 39

Page 41: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

if(D[i]==Temp) D[i]=D[j] Tăng số cạnh tìm được lên 1 (Dem++). Bước 2: Nếu Dem = n-1 thì thuật toán kết thúc. Chú ý: trong qua trình tìm có thể tạo thành rất nhiều cây nhưng kết quả tìm được cuối cùng là một cây thông qua quá trình ghép cây.

CHƯƠNG TRÌNH MẪU

1) Thuật toán Prim tìm cây phủ tối tiểu.

#include <stdio.h> #include <conio.h> #include <iostream.h> #include <values.h> #define FileInt "Bai8.inp" #define FileOut "Bai8.out" /*Lưu lại những cạnh đã đi qua x->y*/ typedef struct Egde { int x,y; }; /*Doc dữ liệu từ file*/ void Doc_File(int **A,int &n){ FILE*f = fopen(FileInt,"rb"); fscanf(f,"%d",&n); *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); } } fclose(f); } /*Ghi dữ liệu ra file*/ void Ghi_File(Egde*L,int n,int Sum) { FILE*f = fopen(FileOut,"wb"); fprintf(f,"%d\n",Sum); for(int i =0; i<n-1; i++) fprintf(f,"%d - %d\n",L[i].x+1,L[i].y+1); fclose(f); } /*Thuật toán Prim*/

Biên Soạn: Đào Anh Pha Trang 40

Page 42: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

void Prim(int **A, int n){ char *D = new char[n]; /*Dánh dấu đỉnh*/ Egde *L = new Egde[n-1]; /*Lưu đường đi */ int min = MAXINT, Dem = 0, Sum = 0; /*Khoi tạo giá trị cho mảng đánh dấu*/ for(int i=0; i<n; i++) D[i]=0; /*Tìm cạnh nhỏ nhất đầu tiên xuất phát từ đỉnh 1*/ for(int j=1; j<n; j++) if(min>A[0][j] && A[0][j]!=0){ min = A[0][j]; L[0].y = j; } L[0].x = 0; D[0] = D[L[0].y] = 1; Sum+=min; Dem++; /*Thực hiện cho đến khi số cạnh tìm được là n-1 cạnh*/ do{ min = MAXINT; for( i=0; i<n; i++) if(D[i]==1) for( j=0; j<n; j++) if(A[i][j]>0 && min>A[i][j] && D[j]==0){ min = A[i][j]; L[Dem].x = i; L[Dem].y = j; } Sum+=min; D[L[Dem].y] = 1; Dem++; } while(Dem<n-1); Ghi_File(L,n,Sum); /*Ghi kết quả tìm được vào file*/ } /*Chương trình chính*/ void main() { int **A,n; Doc_File(A,n); Prim(A,n); delete *A; }

Biên Soạn: Đào Anh Pha Trang 41

Page 43: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

2) Thuật toán Kruskal tìm cây phủ tối tiểu.

void Kruskal(int **A, int n){ char *D = new char[n]; Egde *L = new Egde[n-1]; int min, Dem = 0, Sum = 0, T = 0, Temp; for(int i=0; i<n; i++) D[i] = 0; do{ min = MAXINT; for( i=0; i<n; i++) for(int j=0; j<n; j++) if(A[i][j]>0 && min>A[i][j]&& !(D[i]!=0 && D[i]==D[j])) { min = A[i][j]; L[Dem].x = i; L[Dem].y = j; } /*Tạo ra cây mới*/ if(D[L[Dem].x] ==0 && D[L[Dem].y] == 0){ T++; D[L[Dem].x] = D[L[Dem].y] = T; } /*Đưa đỉnh tương ứng vào cây*/ if(D[L[Dem].x] == 0 && D[L[Dem].y] != 0) D[L[Dem].x] = D[L[Dem].y]; /*Đưa đỉnh tương ứng vào cây*/ if(D[L[Dem].x] != 0 && D[L[Dem].y] == 0) D[L[Dem].y] = D[L[Dem].x]; /*Ghép 2 cây thành 1 cây mới*/ if(D[L[Dem].x] != D[L[Dem].y] && D[L[Dem].y]!=0) { Temp = D[L[Dem].x]; for( i=0; i<n; i++) if(Temp==D[i]) D[i]=D[L[Dem].y]; } Sum+=min; Dem++; } while(Dem<n-1); Ghi_File(L,n,Sum); }

Biên Soạn: Đào Anh Pha Trang 42

Page 44: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 9

Có n thành phố được đánh số từ 1 đến n. Mạng lưới giao thông giữa các thành phố là đường hai chiều. Trên đường đi (nếu có) từ thành phố i đến thành phố j, người ta không được mang quá A[i,j] đơn vị hàng. Nếu không có đường đi từ thành phố i đến thành phố j thì xem như A[i,j] = 0. Cần vận chuyển hàng từ thành phố D đến thành phố C. Hãy thiết lập kế hoạch vận chuyển sao cho khối lượng hàng vận chuyển là nhiều nhất. Dữ liệu vào: đồ thị đã liên thông và cho trong file Bai9.inp với nội dung

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình kế hoạch vận chuyển từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được. Ví dụ: Bai9.inp Kết quả: 6 KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 2

1 6 1->3->4->6 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 Bai9.inp Kết quả: 6 KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 3

1 6 1->3->4->2->5->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

Biên Soạn: Đào Anh Pha Trang 43

Page 45: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN THUẬT TOÁN Sử dụng phương pháp tối ưu theo từng đỉnh giống thuật toán DIJKSTRA.

HƯỚNG DẪN CÀI ĐẶT

Khởi tạo:

- Mọi nhãn ban đầu bằng vô cùng.

- Tất cả các đỉnh chưa được đánh dấu

- Trước mọi đỉnh là đỉnh đầu.

- Đánh dấu đỉnh xuất phát.

Xét đỉnh xuất phát là đỉnh XP:

- Nếu A[XP][j]>0, j chưa được đánh dấu và Nhan[j] = vô cùng thì:

Nhan[j] = min{Nhan[XP],A[XP][j]}

Truoc[j] = XP

- Nếu A[XP][j]>0, j chưa được đánh dấu, Nhan[j] khác vô cùng và min{Nhan[XP],A[XP][j]}>Nhan[j] thì:

Nhan[j] = min{Nhan[XP],A[XP][j]}

Trước[j] = XP

Xét đỉnh xuất phát tiếp theo:

Đỉnh xuất phát tiếp theo là đỉnh chưa được đánh dấu và nhãn của đỉnh phải lớn nhất nhưng khác vô cùng. Khi chọn được đỉnh xuất phát ta phải đánh dấu đỉnh XP.

Minh họa thuật toán: Xét đồ thị dưới đây, hãy lập kế hoạch vận chuyển hàng nhiều nhất từ đỉnh 1 đến đỉnh 6.

Khởi tạo:

Đỉnh 1 2 3 4 5 6

Nhãn ∞ ∞ ∞ ∞ ∞ ∞

Đánh dấu 1* 0 0 0 0 0

Trước 1 1 1 1 1 1

Biên Soạn: Đào Anh Pha Trang 44

Page 46: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

- Xuất phát là đỉnh 1: dánh dấu đỉnh 1.

Đỉnh 1 2 3 4 5 6

Nhãn ∞ 1 2 ∞ ∞ ∞

Đánh dấu 1* 0 0 0 0 0

Trước 1 1 1 1 1 1

- Xuất phát là đỉnh 3: đánh dấu đỉnh 3 (đỉnh 3 là đỉnh có nhãn lớn nhất khác vô cùng và chưa được đánh dấu).

Đỉnh 1 2 3 4 5 6

Nhãn ∞ 2 2 2 2 ∞

Đánh dấu 1 0 1* 0 0 0

Trước 1 3 1 3 3 1

- Xuất phát là đỉnh 2: đánh dấu đỉnh 2 (đỉnh 2 là đỉnh có nhãn lớn nhất khác vô cùng và chưa được đánh dấu).

Đỉnh 1 2 3 4 5 6

Nhãn ∞ 2 2 2 2 ∞

Đánh dấu 1 1* 1 0 0 0

Trước 1 3 1 3 3 1

- Xuất phát là đỉnh 4: đánh dấu đỉnh 4 (đỉnh 4 là đỉnh có nhãn lớn nhất khác vô cùng và chưa được đánh dấu).

Đỉnh 1 2 3 4 5 6

Nhãn ∞ 2 2 2 2 2

Đánh dấu 1 1 1 1* 0 0

Trước 1 3 1 3 3 4

- Xuất phát là đỉnh 5: đánh dấu đỉnh 5 (đỉnh 5 là đỉnh có nhãn lớn nhất khác vô cùng và chưa được đánh dấu).

Đỉnh 1 2 3 4 5 6

Nhãn ∞ 2 2 2 2 2

Đánh dấu 1 1 1 1 1* 0

Trước 1 3 1 3 3 4

- Xuất phát là đỉnh 6: đánh dấu đỉnh 6. Đỉnh xuất phát bằng đỉnh đi đến nên thuật toán kết thúc và trọng tải lớn nhất là 2, kế hoạch vận chuyển qua các con đường là: 6 — 4 — 3 — 1.

Biên Soạn: Đào Anh Pha Trang 45

Page 47: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

CHƯƠNG TRÌNH MẪU

#include <stdio.h> #include <conio.h> #include <iostream.h> #include <values.h> #define FileIn "Bai9.inp" /*Dọc file dữ liệu của bài tóan*/ void Doc_File(int**A, int &n, int &D, int &C){ FILE*f = fopen(FileIn,"rb"); fscanf(f,"%d%d%d",&n,&D,&C); cout<<"Ma Tran Lien Ket Tuong Ung.\n"; cout<<D<<" "<<C<<endl; *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<A[i][j]<<" "; } cout<<endl; } fclose(f); D--; C--; } /*Thủ tục tìm đường đi vận chuyển hàng nhiều nhất*/ void VanChuyen(int **A, int n, int D, int C) { char *DanhDau = new char[n]; int *Nhan = new int[n]; int *Truoc = new int[n]; int XP, min,max; for(int i=0; i<n; i++){ Nhan[i] = MAXINT; DanhDau[i] = 0; Truoc[i] = D; } DanhDau[D] = 1; XP = D; while(XP != C){ for(int j=0; j<n; j++) if(A[XP][j]>0&&DanhDau[j]==0){

Biên Soạn: Đào Anh Pha Trang 46

Page 48: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

if(Nhan[j]==MAXINT){ if(Nhan[XP]>A[XP][j]) Nhan[j] = A[XP][j]; else Nhan[j] = Nhan[XP]; Truoc[j] = XP; } if(Nhan[j]!=MAXINT){ if(Nhan[XP]>A[XP][j]) min = A[XP][j]; else min = Nhan[XP]; if(Nhan[j]<min){ Nhan[j] = min; Truoc[j] =XP; } } } max = 0; for(j=0; j<n; j++) if(Nhan[j]<MAXINT&&DanhDau[j]==0&&max<Nhan[j]){ max = Nhan[j]; XP = j; } DanhDau[XP] = 1; } cout<<"Van chuyen nhieu nhat la: "<<Nhan[C]; cout<<"\nCon duong van chuyen nhu sau:\n"; cout<<C+1<<" <- "<<Truoc[C]+1; i = Truoc[C]; while(i!=D){ i = Truoc[i]; cout<<" <- "<<i+1; } } /*Chương trình chính*/ void main() { clrscr(); int**A,n,Dau,Cuoi; Doc_File(A,n,Dau,Cuoi); VanChuyen(A,n,Dau,Cuoi); delete*A; getch(); }

Biên Soạn: Đào Anh Pha Trang 47

Page 49: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

BÀI TOÁN 10

Có n thành phố biết rằng đường đi giữa các thành phố là đường đi hai chiều. Sơ đồ mạng lưới giao thông của n thành phố cho bởi ma trận A[i,j] trong đó:

- A[i,j] là độ dài đường đi từ thành phố i đến thành phố j. - A[i,j] = 0 nếu không có đường đi từ thành phố i đến thành phố j. - A[i,j] = A[j,i] - A[i,j] nguyên, không âm.

Hãy xác định đường đi dài nhất từ thành phố D đến thành phố C với điều kiện thành phố đã qua không được đi lại. Dữ liệu vào:đồ thị đã liên thông và cho trong file Bai10.inp

- Dòng đầu ghi số n là số đỉnh của một đồ thị (0<n<100) - Dòng thứ hai lưu đỉnh D và đỉnh C. - Dòng i+2 ( ) chứa n số A[i,1],A[i,2]…A[i,n] mỗi số cách nhau bởi

một khoảng trắng. ni ≤≤1

Dữ liệu ra: xuất ra màn hình đường đi dài nhất từ đỉnh D đến C và giá trị đường đi ngắn nhẩt tìm được.

Ví dụ:

Bai10.inp Kết quả: 6 DUONG DI DAI NHAT LA: 16 1 6 1->2->4->3->5->6 0 1 2 0 0 0 1 0 2 2 3 0 2 2 0 5 4 0 0 2 5 0 3 2 0 3 4 3 0 4 0 0 0 2 4 0 Bai10.inp Kết quả: 6 DUONG DI DAI NHAT LA: 25 1 6 1->3->4->2->5->6 0 1 4 0 0 0 1 0 2 6 5 0 4 2 0 7 3 0 0 6 7 0 0 1 0 5 3 0 0 3 0 0 0 1 3 0

HƯỚNG DẪN THUẬT TOÁN Sử dụng kỹ thuật tìm kiếm theo chiều sâu.

Biên Soạn: Đào Anh Pha Trang 48

Page 50: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

HƯỚNG DẪN CÀI ĐẶT Sử dụng kỹ thuật cài đặt tìm kiếm theo phương pháp đệ quy, khi tìm được 1 phương án thì lưu lại trạng thái của phương án ban đầu và so sánh với phương án mới tìm được, nếu phương án mới tốt hơn thì chọn phương án mới.

CHƯƠNG TRÌNH MẪU

include <stdio.h> #include <conio.h> #include <iostream.h> #define Filename "Bai10.inp" /*Khai báo các biến toàn cục*/ int*L,*L1; //Luu lai duong da di char*DanhDau; //Danh dau dinh da di int **A,n,D,C,Tong,Tong1,Canh1; /*Dọc file dữ liệu của bài toán*/ void Doc_File() { FILE*f = fopen(Filename,"rb"); fscanf(f,"%d%d%d",&n,&D,&C); cout<<"Ma Tran Lien Ket Tuong Ung.\n"<<D<<" "<<C<<endl; *A = new int [n]; for(int i =0;i<n;i++) { A[i] = new int [n]; for(int j =0;j<n;j++) { fscanf(f,"%d",&A[i][j]); cout<<A[i][j]<<" "; } cout<<endl; } fclose(f); D--; C--; } /*Khởi tạo ban đầu cho thủ tục tìm kiếm*/ void KhoiTao() { DanhDau = new char [n]; L = new int [n]; //Lưu đường đi tìm được L1 = new int [n]; //Lưu đường đi lớn nhất for (int i = 0; i<n; i++) { DanhDau[i] = 0; //Các đỉnh chưa được đánh dấu L[i] = 0; } DanhDau[D] = 1; //Dánh dấu đỉnh xuẩt phát L[0] = D; //Đường đi đầu tiên qua đỉnh đầu

Biên Soạn: Đào Anh Pha Trang 49

Page 51: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

Tong = 0; //Trong số đường đi Tong1 = 0; //Lưu lại trọng số lớn nhất của đường đi } /*In đường đi dài nhất tìm được*/ void InDuongDi() { cout<<"\nDUONG DI DAI NHAT:"<<Tong1<<endl<<D+1; for (int i = 1; i<Canh1; i++) cout<<" -> "<<L1[i]+1; } /*Xử lý để lấy phương án tổt hơn*/ void XuLy(int Canh) { if(Tong>Tong1){ Tong1 = Tong; //Lưu lại trọng số tốt hơn Canh1 = Canh; //Lưu lại số cạnh đã đi qua for(int i =0; i<Canh; i++) L1[i] = L[i]; //Lưu lại đường đi tốt hơn } } /*Thủ tục tìm kiếm đệ quy*/ void TimKiem(int SoCanh) { if(L[SoCanh-1] == C) XuLy(SoCanh); else { for(int i = 0; i<n; i++) if( A[L[SoCanh-1]][i]>0 && DanhDau[i] == 0){ L[SoCanh] = i; DanhDau[i] = 1; Tong+=A[L[SoCanh-1]][i]; TimKiem(SoCanh+1); L[SoCanh] = 0; Tong-=A[L[SoCanh-1]][i]; DanhDau[i] = 0; } } } void main() { Doc_File(); KhoiTao(); TimKiem(1); if(Tong1==0) cout<<"\NKHONG CO DUONG DI"; else InDuongDi(); delete*A,DanhDau,L; getch(); }

Biên Soạn: Đào Anh Pha Trang 50

Page 52: LYÙ THUYEÁT ÑOÀ THÒ VAØ THUAÄT GIAÛIdulieu.tailieuhoctap.vn/books/cong-nghe-thong-tin/.../file_goc_771587.pdf · trình khác nhau) hay thông báo không tồn tại đường

Giáo Trình Thực Hành Lý Thuyết Đồ Thị

THUẬT TOÁN [] Kiểm tra tính liên thông của đồ thị .............................................................................. [] Đếm số thành phần liên thông của đồ thị .................................................................... [] Thuật toán tìm mọi đường đi từ đỉnh D đến đỉnh C .................................................... [] Thuật toán tìm một đường đi Euler.............................................................................. [] Thuật toán tìm một đường đi Hamilton ....................................................................... [] Thuật toán Dijkstra tìm đường đi ngắn nhất ................................................................ [] Thuật toán Prim tìm cây phủ tối tiểu ........................................................................... [] Thuật toán Kruskal tìm cây phủ tối tiểu ...................................................................... [] Thuật toán đệ quy tìm mọi đường đi Euler.................................................................. [] Thuật toán đệ quy tìm mọi đường đi Hamilton ........................................................... [] Thuật toán toán khử đệ quy tìm mọi đường đi Euler................................................... [] Thuật toán toán khử đệ quy tìm mọi đường đi Hamilton ............................................

Biên Soạn: Đào Anh Pha Trang 51