Tải bản đầy đủ (.pdf) (52 trang)

GIÁO TRÌNH THỰC HÀNH LÝ THUYẾT ĐỒ THỊ VÀ THUẬT GIẢI

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (908.38 KB, 52 trang )

BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC DÂN LẬP CỬU LONG
KHOA CÔNG NGHỆ THÔNG TIN
W€X

GIÁO TRÌNH THỰC HÀNH

LÝ THUYẾT ĐỒ THỊ VÀ
THUẬT GIẢI

Biên Soạn: ĐÀO ANH PHA

Vónh Long, 05/2006


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


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- Dòng i+1 ( 1 ≤ i ≤ n ) 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.
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

011000
100110
100010
010010
011101
000010

Bac cao nhat: 4

Bai1.inp

Kết quả:

5
01001
10111
01001
01001
11110

Bac cao nhat: 4

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ẻ.
Kết quả:
Ví dụ:

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


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- Dòng i+1 (1 ≤ i ≤ n ) 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.
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
00001

00100
01010
00101
10010

DO THI LIEN THONG

Bai2.inp

Kết quả:

8
01000100
10100000
01010000
00101000
00010100
10001010
00000101
00000010

DO THI LIEN THONG

Bai2.inp

Kết quả:

6
011000
101000

110000
000011
000101
000110

DO THI KHONG LIEN THONG

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

Trang 3


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
011000
101000
110000
000011
000101

000110

2

Bai3.inp

Kết quả:

5
00001
00100
01010
00101
10010

1

Bai3.inp

Kết quả:

8
01000100
10100000
01010000
00101000
00010100
10001010
00000101
00000010


1

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

Trang 4


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- Dòng thứ hai lưu đỉnh D và đỉnh C.
- Dòng i+2 (1 ≤ i ≤ n ) 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.
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
15
01001

10110
01010
01101
10010

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

Bai3.inp

Kết quả:

5
15
01011
10101
01010
10101
11010

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

Bai4.inp

Kết quả:


6
14
011000
101000
110000
000011
000101
000110

KHONG CO DUONG DI TU 1 DEN 4

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

Trang 5


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- Dòng i+1 ( 1 ≤ i ≤ n ) 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.
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
01000
10111
01010
01101
01010

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

Bai5.inp

Kết quả:

5
01000
10111
01011
01101
01110

KHONG TON TAI DUONG DI

Bai5.inp

Kết quả:

5

01001
10110
01010
01101
10010

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

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

Trang 6


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- Dòng 2 ghi đỉnh mà người khách du lịch xuất phát.
- Dòng i+1 ( 1 ≤ i ≤ n ) 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.
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
01000
10111
01010
01101
01010

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

Bai6.inp

Kết quả:

6
1
011000
101010
110001
000010
010100
001000

KHONG TON TAI DUONG DI

Bai6.inp

Kết quả:


6
1
011000
101000
110000
000011
000101
000110

KHONG TON TAI DUONG DI

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

Trang 7


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- Dòng thứ hai lưu đỉnh D và đỉnh C.
- Dòng i+2 (1 ≤ i ≤ n ) 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.
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

16

1->2->4->6

012000
102230
220540
025032
034304
000240

Bai7.inp

Kết quả:

6

DUONG DI NGAN NHAT LA: 8


16
014000
102650
420730
067001
053003
000130

1->2->4->6

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

Trang 8


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ị (0Dòng i+1 (1 ≤ i ≤ n ) 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.
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
03322
30232
32014
23104
22440

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

Bai8.inp
8
02340000
20304000
33076520
40700030
04600408

00504016
00230105
00008650

Bai8.out
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


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- Dòng thứ hai lưu đỉnh D và đỉnh C.

- Dòng i+2 (1 ≤ i ≤ n ) 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.
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
16
012000
102230
220540
025032
034304
000240

KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 2
1->3->4->6

Bai9.inp
Kết quả:
6
16
014000
102650
420730
067001
053003
000130


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

KHOI LUONG VAN CHUYEN NHIEU NHAT LA: 3
1->3->4->2->5->6

Trang 10


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- Dòng thứ hai lưu đỉnh D và đỉnh C.
- Dòng i+2 (1 ≤ i ≤ n ) 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.
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

16

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

012000
102230
220540
025032
034304
000240

Bai10.inp

Kết quả:

6

DUONG DI DAI NHAT LA: 25

16
014000
102650
420730
067001
053003

000130

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

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

Trang 11


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- Dòng i+1 ( 1 ≤ i ≤ n ) 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.
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
011000
100110
100010
010010
011101

000010

Bac cao nhat: 4

Bai1.inp

Kết quả:

5
01001
10111
01001
01001
11110

Bac cao nhat: 4

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ụ:

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

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.

Trang 12


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).
9 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.
9 Đỉ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.
9 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.
9 Đỉ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.
9 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.
9 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ẻ.
9 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;iA[i] = new int [n];
cout<for(int j =0;jfscanf(f,"%d",&A[i][j]);
cout<<" "<}
}
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


Giáo Trình Thực Hành Lý Thuyết Đồ Thị
for(int i = 0; iBac = 0;
for(int j = 0; jif(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; iBac = 0;
for(int j = 0; jif(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; ifor(int j = 0; jif(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; iBac = 0;
for(int j = 0; jif(A[i][j]>0)
Bac++;
if(Bac == min)
cout<<" "<Biên Soạn: Đào Anh Pha

Trang 14


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; iBac = 0;
for(int j = 0; jif(A[i][j]>0)
Bac++;
if(Bac == max)
cout<<" "<}
}
/*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; iBac = 0;
for(int j = 0; jif(A[i][j]>0)
Bac++;
if(Bac%2==0) {
cout<<" "<Tong++;
}
}
cout<<"\n\t So Dinh Bac Chan: "<}
/*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; iBac = 0;
for(int j = 0; jif(A[i][j]>0)
Bac++;
if(Bac%2==1) {
cout<<" "<Tong++;
}
}
Biên Soạn: Đào Anh Pha

Trang 15



Giáo Trình Thực Hành Lý Thuyết Đồ Thị
cout<<"\n\t So Dinh Bac Le: "<}
/*Chuong Trinh Chinh*/
void main() {
clrscr();
int **A,n;
Doc_File(A,n);
cout<<"\n1. Bac Lon Nhat Cua Dinh: "<cout<<"\n2. Dinh Co Bac Lon Nhat:";
DinhBacLonNhat(A,n);
cout<<"\n3. Bac Nho Nhat Cua Dinh: "<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: "<delete*A;
getch();
}

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

Trang 16


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- Dòng i+1 (1 ≤ i ≤ n ) 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.
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
00001
00100
01010
00101
10010

DO THI LIEN THONG

Bai2.inp

Kết quả:

8

01000100
10100000
01010000
00101000
00010100
10001010
00000101
00000010

DO THI LIEN THONG

Bai2.inp

Kết quả:

6
011000
101000
110000
000011
000101
000110

DO THI KHONG LIEN THONG

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

Trang 17



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≤kkhô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;iA[i] = new int [n];
cout<
Biên Soạn: Đào Anh Pha

Trang 18


Giáo Trình Thực Hành Lý Thuyết Đồ Thị
for(int j =0;jfscanf(f,"%d",&A[i][j]);
cout<<" "<}
}
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; iDanhDau[i] = 0;
DanhDau[0] = 1;
Dem++;
do { ThanhCong =1;
for(i = 0; iif(DanhDau[i]==1) {
for(int j = 0; jif (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


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
011000
101000
110000
000011
000101
000110

2

Bai3.inp


Kết quả:

5
00001
00100
01010
00101
10010

1

Bai3.inp
8
01000100
10100000
01010000
00101000
00010100
10001010
00000101
00000010

Kết quả:
1

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


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; iDanhDau[i] = 0;
do { j = 0;
while(DanhDau[j]==1)
j++;
DanhDau[j] = 1;

Dem++;
MLT++;
do {
ThanhCong =0;
for(i = 0; iif(DanhDau[i]==1)
for(j = 0; jif (DanhDau[j] == 0 && A[i][j] > 0) {
DanhDau[j] = 1;
ThanhCong =1;
Dem++;
if(Dem == n) return MLT;
}
}while (ThanhCong == 1);
} while(Demreturn MLT;
}

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

Trang 21


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- Dòng thứ hai lưu đỉnh D và đỉnh C
- Dòng i+2 (1 ≤ i ≤ n ) 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.
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
15
01001
10110
01010
01101
10010

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

Bai3.inp

Kết quả:

5
15

01011
10101
01010
10101
11010

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

Bai4.inp

Kết quả:

6
14
011000
101000
110000
000011
000101
000110

KHONG CO DUONG DI TU 1 DEN 4

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

Trang 22



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<*A = new int [n];
for(int i =0;iA[i] = new int [n];
for(int j =0;j

fscanf(f,"%d",&A[i][j]);
cout<}
cout<}
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//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


Giáo Trình Thực Hành Lý Thuyết Đồ Thị
DanhDau[D] = 1;
L[0] = D;

//Đánh dấu đỉnh đầu tiên
//Lưu lại đỉnh đầu tiên là đỉnh xuất phát


}
void InDuongDi(int SoCanh) {
Dem++;
cout<for (int i = 1; icout<<" -> "<}
/*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; iif( 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 "<TimKiem(1);

if(Dem==0)
cout<<" khong co";
delete*A,DanhDau,L;
getch();
}

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

Trang 24


×