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

Bài tập toán rời rạc 2 Bộ môn Công nghệ phần mềm

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 (757.75 KB, 58 trang )

MỤC LỤC
Bài 1 Các khái niệm cơ bản của lý thuyết ñồ thị
3

Mục tiêu 3

a. Nhắc lại lý thuyết 3

b. ðề bài tập 3

c. Hướng dẫn giải 4

d. Bài tập tự giải 5

Bài 2 Biểu diễn ñồ thị trên máy tính
6

Mục tiêu 6

a. Nhắc lại lý thuyết 6

b. ðề bài tập 6

c. Hướng dẫn giải 7

d. Bài tập tự giải 10

Bài 3 ðồ thị Euler
12

Mục tiêu 12



a. Nhắc lại lý thuyết 12

b. ðề bài tập 13

c. Hướng dẫn giải 13

d. Bài tập tự giải 14

Bài 4 ðồ thị Hamilton
15

Mục tiêu 15

a. Nhắc lại lý thuyết 15

b. ðề bài tập 15

c. Hướng dẫn giải 15

d. Bài tập tự giải 19

Bài 5 Thảo luận cài ñặt ñồ thị, các thuật toán liệt kê chu trình Euler và Hamilton.20

Bài 6 Thuật toán tìm kiếm trên ñồ thị và ứng dụng
20

Mục tiêu 20

a. Nhắc lại lý thuyết 20


b. ðề bài tập 20

c. Hướng dẫn giải 21

d. Bài tập tự giải 28

Bài 7

Cây và cây khung
29

Mục tiêu 29

a. Nhắc lại lý thuyết 29

b. ðề bài tập 30

c. Hướng dẫn giải 30

d. Bài tập tự giải 36

Bài 8 Thảo luận về cài ñặt thuật toán tìm cây khung nhỏ nhất trên ñồ thị
38

Bài 9, 10 Bài toán tìm ñường ñi ngắn nhất
38

Mục tiêu 38


a. Nhắc lại lý thuyết 38

b. ðề bài tập 38

c. Hướng dẫn giải 40

d. Bài tập tự giải 47

Bài 12 Bài toán luồng cực ñại trong mạng
50

Mục tiêu 50

a. Nhắc lại lý thuyết 50

b. ðề bài tập 51

c. Hướng dẫn giải 51

d. Bài tập tự giải 53


Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 2

LỜI NÓI ðẦU
Có thể nói toán học rời rạc là môn tiên quyết và hiệu quả nhất ñể người học nâng cao
tư duy toán học trong phân tích, thiết kế thuật toán và rèn luyện kỹ năng lập trình với những
thuật toán phức tạp. Không những thế nó còn là “cửa ngõ” ñể người học có thể tiếp cận với
rất nhiều modul trong khoa học máy tính (như Chương trình dịch, lý thuyết tính toán, Trí

tuệ nhân tạo, ). Bài tập ñể củng cố và nâng cao kiến thức trong môn học này
Về nội dung, bám sát với chương trình của nhà trường và hệ thống bài tập cũng ñược
biên soạn theo các chương lý thuyết. Với mỗi bài sẽ ñược chia thành 4 phần:
Phần A. Nhắc lại lý thuyết: tóm tắt các kiến thức cơ bản, các ví dụ và các lưu ý hữu
ích, các kinh nghiệm trong khi lập trình
Phần B. ðề bài tập: ñưa ra các loại bài tập khác nhau, với các mức ñộ khác nhau.
Phần C. Bài tập mẫu: Hướng dẫn giải một số bài tiêu biểu trong phần B, có phân
tích thuật toán và cài ñặt chương trình.
Phần D. Bài tập tự giải: Người học thực hiện việc giải các bài tập này.
Mong rằng tài liệu này ñáp ứng ñược phần nào nhu cầu của học sinh, sinh viên.


Bộ môn:

Công ngh
ệ phần mềm

Khoa: Công nghệ thông tin
Trường: ðại học sư phạm kỹ thuật Hưng Yên


Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 3

Bài 1 Các khái niệm cơ bản của lý thuyết ñồ thị
Mục tiêu
- Lưu trữ ñược ñồ thị trên máy tính theo những phương pháp khác nhau.
- Cài ñặt ñược chương trình chuyển ñổi giữa các phương pháp.
- Sinh viên có khả năng tự học.
a. Nhắc lại lý thuyết

- ðơn ñồ thị vô hướng (ðịnh nghĩa 1.1)
- ða ñồ thị vô hướng (ðịnh nghĩa 1.2)
- ðơn ñồ thị có hướng (ðịnh nghĩa 1.4)
- ða ñồ thị có hướng (ðịnh nghĩa 1.5)
- ðường ñi ñộ dài n (ðịnh nghĩa 1.6)
- Chu trình là ñường ñi có ñỉnh ñầu trùng với ñỉnh cuối.
- ðường ñi (chu trình) ñược gọi là ñơn nếu như không có cạnh nào bị lặp lại.
- ðồ thị vô hướng liên thông (ðịnh nghĩa 1.8)
- ðồ thị có hướng liên thông mạnh (ðịnh nghĩa 1.11)
- ðồ thị có hướng liên thông yếu (ðịnh nghĩa 1.12)
- Cầu (ðịnh nghĩa 1.10)
- ðồ thị ñịnh hướng ñược: ðồ thị vô hướng liên thông là ñịnh hướng ñược khi và chỉ
khi mỗi cạnh của nó nằm trên ít nhất một chu trình. (ðịnh lý 1.1)
- ðỉnh kề: ðỉnh V ñược gọi là kề với ñỉnh U nếu có cạnh (U,V)
- Biểu diễn ñồ thị G(V,E) dạng hình học
Biểu diễn ñỉnh: lấy các ñiểm trên mặt phẳng hay trên không gian tương ứng với các
phần tử của tập V và dùng ngay ký hiệu các phần tử này ñẻ ghi trên các ñiểm tương ứng.
Biểu diễn cạnh: Nếu cạnh e với hai ñỉnh ñầu là A, B thì nó ñược biểu diễn bằng ñoạn
thẳng hay một ñoạn nối giữa hai ñiểm A, B và không ñi qua các ñiểm tương ứng trong
không gian.
Biểu diễn cung: nếu cung e có ñỉnh ñầu là C, ñỉnh cuối là D, thì nó ñược biểu diễn
bằng một ñoạn thẳng hoặc ñoạn cong ñược ñịnh hướng ñi từ C sang D và không qua các
ñiểm tương ứng trung gian khác.
Chú ý: Hình nhận ñược gọi là dạng biểu diễn hình học của ñồ thị G(V, E). ðôi khi
người ta cũng gọi dạng biểu diễn hình học là một ñồ thị.
b. ðề bài tập
Bài 1 Cho G ñồ thị gồm 4 phần G1, G2, G3 và G4 như sau:
a. Chỉ ra tập ñỉnh, cạnh(vô hướng,có hướng, khuyên, ) của mỗi ñồ thị ñã cho? Chỉ loại ñồ
thị ñó?
b. ðồ thị G, G1, G2, G3, G4 và G5 có liên thông không? Nếu ñồ thị không liên thông hãy

chỉ ra các thành phần liên thông?
c. ðồ thị G, G1, G2, G3, G4 và G5 có chu trình không? Chỉ ra các chu trình của ñồ thị (nếu
có)?
A

B

C

D

Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 4



c. Hướng dẫn giải
Bài 1
a.
Tên ñồ thị Tập ñỉnh V Tập cạnh E Loại ñồ thị
G1 1, 2, 3, 4 (1,2); (1,4); (2,3); (2,4); (3,4) Vô hướng
G2 5, 6, 7 (5,7); (6,5); (6,7) Có hướng
G3 8, 9 (8,9) Vô hướng
G4 0
G 1, 2, 3, 4, 5, 6, 7,
8, 9, 0
(1,2); (1,4); (2,3); (2,4); (3,4);
(8,9); (5,7); (6,5); (6,7)
Hỗn hợp


b.
Tên ñồ thị Tính liên thông Tên thành phần liên thông
G1 Có G1
G2 Có G2
G3 Có G3
G4 Có G4
G Không G1, G2, G3, G4

c.
Tên ñồ thị Có chu trình? Tên chu trình
G1 Có (1, 2, 4, 1); (1, 2, 3, 4, 1); (2, 3, 4, 2)
G2 Không
G3 Không
G4 Không
G Có (1, 2, 4, 1); (1, 2, 3, 4, 1); (2, 3, 4, 2)

G
1

1

4
3

2

5
7

6


8

9

0
G
2

G
3

G
4

Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 5

d. Bài tập tự giải
Bài tập 1 ðồ thị sau là ñồ thị vô hướng hay ñồ thị có hướng? ðưa ra các cạnh vô hướng
(nếu có) của ñồ thị? ðưa ra các cạnh có hướng (nếu có) của ñồ thị? Tính bậc các ñỉnh của
ñồ thị vô hướng? Tính bậc vào(ra) của các ñỉnh trên ñồ thị có hướng? Kiểm tra tính liên
thông của ñồ thị? ðưa ra 1 ñường ñi ñộ dài 5 của ñồ thị? Chỉ ra ít nhất 1 chu trình của ñồ thị
(nếu có)?


Bài tập 2 Khi về nghỉ hè mỗi bạn sinh viên của lớp TK7 trường ðHSPKTHY ñều trao ñổi
ñịa chỉ với ít nhất một nửa số bạn trong lớp. Chứng minh rằng trong thời gian nghỉ hè mỗi
bạn của lớp TK7 ñều có thể báo tin trực tiếp hay gián tiếp cho các bạn trong lớp.
Hướng ñẫn:

Bước 1: Xây dựng ñồ thị
• ðỉnh: Lấy các ñiểm trong mặt phẳng hay trong không gian tương ứng với các bạn
học sinh trong lớp TK7.
• Cạnh: Hai ñiểm x, y ñược nối bằng một cạnh khi và chỉ khi các bạn x, y trao ñổi ñịa
chỉ cho nhau.
- ðồ thị ñược ký hiệu bằng G
2
mô tả toàn bộ quan hệ trao ñổi ñịa chỉ trong lớp TK7
Bước 2: Vận dụng kết quả các ñịnh lý ñể suy ra kết luận
Vì mỗi bạn học sinh trong lớp TK7 trao ñổi ñịa chỉ với ít nhất một nửa số bạn trong
lớp, nên bậc của mỗi ñỉnh của G
2
không nhỏ hơn một nửa số ñỉnh của ñồ thị. Khi ñó, ñồ thị
G
2
liên thông. Bởi vậy hai ñỉnh x, y ñều có xích nối với nhau. Khi ñó thông qua các bạn
tương ứng với các ñỉnh thuộc xích
, mà bạn tương ứng với ñỉnh x báo tin ñược cho tương
ứng với ñỉnh y và ngược lại.
Bài tập 3 Trong một cuộc họp có ñúng hai ñại biểu không quen nhau và mỗi ñại biểu này có
một số lẻ người quen ñến dự. Chứng minh rằng luôn luôn có thể xếp một số ñại biểu ngồi
chen giữa hai ñại biểu nói trên, ñể người ngồi giữa hai người mà anh (chị) ta quen.









Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 6

Bài 2 Biểu diễn ñồ thị trên máy tính
Mục tiêu
- Nêu ñược các cách biểu diễn ñồ thị và biểu diễn ñồ thị trên máy tính trên máy tính.
- ðưa ra ñược ma trận kề, danh sách các cạnh, cung tương ứng với 1 ñồ thị cho trước.
- Lưu trữ ñược ñồ thị trên máy tính theo những phương pháp khác nhau.
- Phân tích ñược bài toán thực tế tương ứng phần lý thuyết ñã học.
- Sinh viên có khả năng tự học.
a. Nhắc lại lý thuyết
- Biểu diễn ñồ thị dạng ma trận kề
A=( a
i,j
: i, j = 1, 2, . . . ,n)
a
i,j
= 1 , nếu có cạnh từ i sang j hay (i, j) ∈ E, i, j =1, 2,. . ., n.
a
i, j
= 0, trong trường hợp còn lại tức là không có cạnh(i, j)
- Biểu diễn ñồ thị dạng danh sách các cạnh (cung)
E=(e
i,j
: i= 1, 2, . . . ,m; j = 1, 2)
(e
i,1
,e
i,2
) là cạnh thứ i trong m cạnh (cung) của ñồ thị.

- Biểu diễn ñồ thị dạng danh sách kề
Ke(v)= { u ∈ V: (v,u)∈ E }

b. ðề bài tập
Bài 1 Cho G ñồ thị gồm 4 phần G1, G2, G3 và G4 như sau:

a. Biểu diễn các ñồ thị G,G1,G2,G3,G4 dưới dạng ma trận kề
b. Biểu diễn các ñồ thị G,G1,G2,G3,G4 dưới dạng danh sách cạnh(cung)
c. Biểu diễn các ñồ thị G,G1,G2,G3,G4 dưới dạng danh sách kề
Bài 2 Xây dựng chương trình ñọc dữ liệu từ file text (ñồ thị biểu diễn dạng danh sách cạnh)
và lưu vào ma trận kề và hiển thị ra màn hình.

G
1

1

4
3

2

5
7

6

8

9


0
G
2

G
3

G
4

Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 7

c. Hướng dẫn giải
Bài 1
Tên ñồ thị a. ma trận kề b. danh sách
cạnh(cung)
c.danh sách kề
G1 1 2 3 4
1 0 1 0 1
2 1 0 0 1
3 0 0 0 1
4 1 1 1 0
Danh sách cạnh
1 2
1 4
2 3
2 4
3 4

1 2 4
2 1 4
3 4
4 1 2 3
G2 5 6 7
5 0 0 1
6 1 0 1
7 0 0 0
Danh sách cung
5 7
6 5
6 7
5 7
6 5 7
G3 8 9
8 0 1
9 1 0
Danh sách cạnh
8 9
8 9
9 8
G4 0
0 0

G 1 2 3 4 5 6 7 8 9 0
1 0 1 0 1 0 0 0 0 0 0
2 1 0 0 1 0 0 0 0 0 0
3 0 0 0 1 0 0 0 0 0 0
4 1 1 1 0 0 0 0 0 0 0
5 0 0 0 0 0 0 1 0 0 0

6 0 0 0 0 1 0 1 0 0 0
7 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0 1 0
9 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0

Danh sách cung
1 2
1 4
2 1
2 3
2 4
3 2
3 4
4 1
4 2
4 3
5 7
6 5
6 7
1 2 4
2 1 4
3 4
4 1 2 3
5 7
6 5 7
8 9
9 8
0


Bài 2 Xây dựng chương trình ñọc dữ liệu từ file text (ñồ thị biểu diễn dạng danh sách cạnh)
và lưu vào ma trận kề và hiển thị ra màn hình.

Chương trình minh họa:
using System;
using System.IO;
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 8

namespace LTDT
{
class mtrke_DScanh
{
//I: "d:/trr/DScanh.in", luu do thi theo DS canh vao tep text
//O: "d:/trr/mtrke.out" Doc tep va ghi BD ma tran ke
static string filenameIN = "d:/dsc";
static string filenameOUT = "d:/mtk";
static public void nhaptep()
{
int m, n, x, A, B;
Console.Write("nhap so dinh cua do thi: n=");
n = int.Parse(Console.ReadLine());
Console.Write("nhap so canh cua do thi: m=");
m = int.Parse(Console.ReadLine());
StreamWriter ft = File.CreateText(filenameIN);
//ghi Dl vao tep DScanh.in
//D1: luu so dinh va so canh
//D2 Dm+1
ft.WriteLine("{0} {1}", n, m); //ghi DL vao D1 cua tep DScanh.in
Console.Write("nhap 2 dau va Trong So");

for (int i = 0; i < m; i++)
{
Console.Write("Canh thu {0}:", i + 1);
A = int.Parse(Console.ReadLine());
B = int.Parse(Console.ReadLine());
x = int.Parse(Console.ReadLine());
ft.WriteLine("{0} {1} {2}", A, B, x); //ghi DL vao
}
ft.Close();
}
//doc tep "d:/trr/DScanh.in", DS canh, ghi BD ma tran ke "d:/trr/mtrke.out"
static public void doctep()
{
try
{
StreamReader fi = new StreamReader(filenameIN);
StreamWriter fo = File.CreateText(filenameOUT);
//lan luot doc DL ve tung canh trong tep DScanh.in, luu Gtr thu dc vao mang a[i,j]
// lan luot ghi Dl tu a[i,j] vao teo mtrke.out
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 9

string s;
int i, j, n, m;
s = fi.ReadLine();
string[] n1 = new string[3]; n1 = s.Split('\t');
n = int.Parse(n1[0]);
m = int.Parse(n1[1]);
int[,] a = new int[n, n]; //mang luu do thi theo mtran ke
//tep "d:/trr/DScanh.out" luu D1 so dinh va so canh cua dthi

//d2 dm+1, Di+1 lan luot luu thong tinh ve canh thu i
for (int k = 0; k < m; k++)
{
s = fi.ReadLine();
j = 0;
n1 = s.Split('\t');
i = int.Parse(n1[0]) - 1;
j = int.Parse(n1[1]) - 1;
a[j, i] = a[i, j] = int.Parse(n1[2]);

}
//ghi Dl vao tep mtrke.out
fo.WriteLine("{0}", n);
//Line 2 n+1, dg i+1: a[i][j],j=0 n-1
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
Console.Write("{0} ", a[i, j]);
fo.Write("{0} ", a[i, j]); //ghi vao tep
}
fo.WriteLine();
Console.WriteLine();
}
fi.Close();
fo.Close();
}
catch (Exception e)
{
Console.WriteLine("Khong the doc duoc noi dung tep");

Console.WriteLine(e.Message);
}
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 10

}
public static void Main()
{
nhaptep();
doctep();
Console.ReadLine();
}
}
}
Kết quả ñầu vào và ñầu ra tương ứng cho chương trình trên
"d:/dsc.in" "d:/mtk.out" "d:/dsc.in" "d:/mtk.out"
6 15
1 2 33
1 3 17
1 4 85
1 5 85
1 6 85
2 3 18
2 4 20
2 5 85
2 6 85
3 4 16
3 5 4
3 6 85
4 5 9

4 6 8
5 6 14
6
0 33 17 85 85 85
33 0 18 20 85 85
17 18 0 16 4 85
85 20 16 0 9 8
85 85 4 9 0 14
85 85 85 8 14 0
9 14
1 2 4
1 8 8
2 3 8
2 8 11
3 4 7
3 6 4
3 9 2
4 5 9
4 6 14
5 6 10
6 7 2
7 8 1
7 9 6
8 9 7
9
0 4 0 0 0 0 0 8 0
4 0 8 0 0 0 0 11 0
0 8 0 7 0 4 0 0 2
0 0 7 0 9 14 0 0 0
0 0 0 9 0 10 0 0 0

0 0 4 14 10 0 2 0 0
0 0 0 0 0 2 0 1 6
8 11 0 0 0 0 1 0 7
0 0 2 0 0 0 6 7 0

d. Bài tập tự giải
Bài tập 1 Biểu diễn ñồ thị dưới dạng dạng ma trận kề, danh sách cạnh, danh sách kề

Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 11

Bài tập 2 Cài ñặt chương trình nhập ñồ thị biểu diễn dạng ma trận kề (danh sách
cạnh(cung), danh sách kề) từ tệp và hiển thị ñồ thị ra màn hình.
Bài tập 3 Cài ñặt chương trình nhập ñồ thị biểu diễn dạng ma trận kề (danh sách
cạnh(cung), danh sách kề) từ tệp và hiển thị ñồ thị biểu diễn dạng còn lại ra màn hình.
Bài tập 4 ðọc dữ liệu từ file text (ñồ thị biểu diễn dạng ma trận kề) và lưu vào danh sách kề
và hiển thị ra màn hình.
Bài tập 5 ðọc dữ liệu từ file text (ñồ thị biểu diễn dạng ma trận kề) và lưu vào danh sách
cạnh và hiển thị ra màn hình.
Bài tập 6 ðọc dữ liệu từ file text (ñồ thị biểu diễn dạng danh sách cạnh) và lưu vào danh
sách kề và hiển thị ra màn hình.
Bài tập 7 ðọc dữ liệu từ file text (ñồ thị biểu diễn dạng danh sách kề) và lưu vào ma trận kề
và hiển thị ra màn hình.
Bài tập 8 ðọc dữ liệu từ file text (ñồ thị biểu diễn dạng danh sách kề) và lưu vào danh sách
cạnh và hiển thị ra màn hình.
Bài tập 9 Cài ñặt chương trình nhập ñồ thị vô hướng biểu diễn dạng ma trận kề (danh sách
cạnh(cung), danh sách kề) từ tệp. Tính bậc các ñỉnh của ñồ thị.
Bài tập 10 Cài ñặt chương trình nhập ñồ thị có hướng biểu diễn dạng ma trận kề (danh sách
cạnh(cung), danh sách kề) từ tệp. Tính bậc vào, bậc ra của các ñỉnh của ñồ thị.
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011

Trang 12

Bài 3 ðồ thị Euler
Mục tiêu
- Kiểm tra ñược một ñồ thị bất kỳ có là ñồ thị euler hay không.
- Áp dụng ñược thuật toán tìm chu trình Euler, ñường Euler, với 1 ñồ thị cho trước.
- Lưu trữ ñược ñồ thị trên máy tính theo những phương pháp khác nhau. Cài ñặt ñược
chương trình chuyển ñổi giữa các phương pháp.
- Cài ñặt ñược thuật toán Tìm chu trình Euler.
- Cài ñặt ñược thuật toán duyêt ñồ thị duyệt theo chiều sâu hoặc duyệt theo chiều rộng.
- Sinh viên có khả năng tự học.
a. Nhắc lại lý thuyết
- Chu trình (t.ư. ñường ñi) ñơn chứa tất cả các cạnh (hoặc cung) của ñồ thị (vô hướng
hoặc có hướng) G ñược gọi là chu trình (t.ư. ñường ñi) Euler. Một ñồ thị liên thông (liên
thông yếu ñối với ñồ thị có hướng) có chứa một chu trình (t.ư. ñường ñi) Euler ñược gọi là
ñồ thị Euler (t.ư. nửa Euler).


ðịnh lý: ðồ thị (vô hướng) liên thông G là ñồ thị Euler khi và chỉ khi mọi ñỉnh của G ñều
có bậc chẵn.
Hệ quả: ðồ thị liên thông G là nửa Euler (mà không là Euler) khi và chỉ khi có ñúng hai
ñỉnh bậc lẻ trong G.
Thuật toán vạch ñược một chu trình Euler trong ñồ thị liên thông G có bậc của mọi ñỉnh là
chẵn theo thuật toán Flor sau ñây.
Xuất phát từ một ñỉnh bất kỳ của G và tuân theo hai quy tắc sau:
1. Mỗi khi ñi qua một cạnh nào thì xoá nó ñi; sau ñó xoá ñỉnh cô lập (nếu có);
2. Không bao giờ ñi qua một cầu, trừ phi không còn cách ñi nào khác.
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 13


b. ðề bài tập
Bài 1 ðồ thị sau có là ñồ thị nửa Euler hay ñồ thị Euler không? Giải thích?
Bài 2 Dùng thuật toán Flor ñể tìm tìm chu trình Euler cho ñồ thị.

c. Hướng dẫn giải
Bài 1 ðồ thị sau có là ñồ thị nửa Euler hay ñồ thị Euler không? Giải thích?

ðồ thị G1 là ñồ thị nửa Euler
Thật vây, các ñỉnh a,b,e có bậc là
2,4,4 là bậc chẵn, các ñỉnh c và d có
bậc là 3 là bậc lẻ

ðồ thị G3 không là ñồ thị Euler
Thật vậy G3 có 3 ñỉnh a,d và g có bậc là 1 là bậc lẻ


ðồ thị G2 là ñồ thị nửa Euler
Thật vây, các ñỉnh c và d có bậc là 2
là bậc chẵn, các ñỉnh a và c có bậc là
1 là bậc lẻ

ðồ thị G4 là ñồ thị nửa Euler vì theo hệ quả
Thật vây, các ñỉnh 3,4,5 có bậc là 2 là bậc chẵn, các ñỉnh 1
và 2 có bậc là 3 là bậc lẻ
1
2
3 4
5
g


a

d

b

c

e

f

G3
a

d

b

c

G2
a

b

e

c


d

G1
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 14

Bài 2 Dùng thuật toán Flor ñể tìm tìm chu trình Euler cho ñồ thị sau:

Xuất phát từ u, ta có thể ñi theo cạnh (u,v) hoặc (u,x), giả sử là (u,v) (xoá (u,v)).
Từ v có thể ñi qua một trong các cạnh (v,w), (v,x), (v,t), giả sử (v,w) (xoá (v,w)).
Tiếp tục, có thể ñi theo một trong các cạnh (w,s), (w,y), (w,z), giả sử (w,s) (xoá (w,s)).
ði theo cạnh (s,y) (xoá (s,y) và s). Vì (y,x) là cầu nên có thể ñi theo một trong hai cạnh
(y,w), (y,z), giả sử (y,w) (xoá (y,w)).
ði theo (w,z) (xoá (w,z) và w) và theo (z,y) (xoá (z,y) và z).
Tiếp tục ñi theo cạnh (y,x) (xoá (y,x) và y).
Vì (x,u) là cầu nên ñi theo cạnh (x,v) hoặc (x,t), giả sử (x,v) (xoá (x,v)).
Tiếp tục ñi theo cạnh (v,t) (xoá (v,t) và v).
Theo cạnh (t,x) (xoá cạnh (t,x) và t).
Cuối cùng ñi theo cạnh (x,u) (xoá (x,u), x và u).
d. Bài tập tự giải
Bài tập 1 ðồ thị sau có là ñồ thị nửa Euler hay ñồ thị Euler không? Dùng thuật toán Flor ñể
tìm chu trình Euler(ñường Euler) nếu ñồ thị nửa Euler(ñồ thị Euler) sau:


Bài tập 2 Một xe chở khách du lịch cần ñi tham quan các con ñường giữa N thành phố (các
thành phố ñược ñánh số từ 0 dến N-1, N<100). Giữa 2 thành phố bất kỳ nếu có ñường ñi
ñến nhau thì bao giờ cũng là ñường 2 chiều, và hai thành phố bất kỳ ñược nối trực tiếp với
nhau bởi nhiều nhất một con ñường.
Liệu có cách nào qua tất cả các ñường, mỗi ñường ñúng 1 lần hay không? Xây dựng giải
thuật và cài ñặt chương trình giúp cho người lái xe khách du lịch.

Bài tập 3 Một trạm quảng ñường giao thông phải chịu trách nhiêm về tình trạng của một
mạng lưới giao thông nối giữa các ñiểm dân cư. Hàng tháng, họ phải cử một ñội ñi kiểm tra
một vòng qua khắp mạng lưới ñể xem xét tình trạng hiện thời của các ñường giao thông
nhằm báo sửa chữa kịp thời nếu có nhu cầu. Hãy viết chương trình nhập vào mạng lưới giao
thông và giúp trạm quyết ñịnh lộ trình của ñội kiểm tra sao cho có thể thăm tất cả các con
ñường mà tổng chiều dài ñoạn ñường ñi qua là nhỏ nhất.
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 15

Bài 4 ðồ thị Hamilton
Mục tiêu
- Kiểm tra ñược một ñồ thị bất kỳ có là ñồ thị Hamilton hay không.
- Áp dụng ñược thuật toán tìm chu trình Hamilton, ñường Hamilton, với 1 ñồ thị cho
trước.
- Lưu trữ ñược ñồ thị trên máy tính theo những phương pháp khác nhau. Cài ñặt ñược
chương trình chuyển ñổi giữa các phương pháp.
- Cài ñặt ñược thuật toán Tìm chu trình Halmiton.
- Cài ñặt ñược thuật toán duyêt ñồ thị duyệt theo chiều sâu hoặc duyệt theo chiều rộng.
- Sinh viên có khả năng tự học.
a. Nhắc lại lý thuyết
- ðồ thị Hamilton (nửa Hamilton) là ñồ thị có chứa một chu trình(ñường ñi) Hamilton
Hay
ðường ñi (x[1], x[2], … , x[n]) ñược gọi là ñường ñi Hamilton nếu x[i]≠x[j] (1≤i<j≤n)
Chu trình (x[1], x[2], …, x[n], x[1]) ñược gọi là chu trình Hamilton nếu x[i]≠x[j]
(1≤i<j≤n)
Note! Cho tới nay, vẫn chưa tìm ra phương pháp với ñộ phức tạp ña thức ñể tìm chu trình
cũng như ñường ñi Hamilton trong trướng hợp ñồ thị tổng quát.
Có thể sử dụng thuật toán quay lui ñể liệt kê chu trình Hamilton

b. ðề bài tập

Bài 1 ðồ thị sau có là ñồ thị nửa Hamilton hay ñồ thị Hamilton không? Giải thích?
Bài 2 Liệt kê tất cả các chu trình Hamilton của ñồ thị.
c. Hướng dẫn giải
Bài 1 ðồ thị sau có là ñồ thị nửa Hamilton hay ñồ thị Hamilton không? Giải thích?

ðồ thị G1 là ñồ thị Hamilton

ðồ thị G3 không có chu trình hay ñường ñi Hamilton

g

a

d

b

c

e

f

G3
a

b

e


c

d

G1
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 16


ðồ thị G2 là ñồ thị nửa Hamilton
ðồ thị G4 là ñồ thị Hamilton, vì có chu trình Hamilton
(1,3,5,2,4,1)
Bài 2 Liệt kê tất cả các chu trình Hamilton của ñồ thị
ðồ thị và cây liệt kê chu trình Hamilton của nó theo thuật toán quay lui.
Trong trường hợp ñồ thị có không quá nhiều cạnh thuật toán trên có thể sử dụng ñể kiểm tra
ñồ thị có phải là Hamilton hay không.
Chương trình minh họa:
using System;
using System.Text;
using System.IO;
namespace Danhsachke
{
class Node
{
public int v;
public Node next;
public Node()
{
this.v = 0;
this.next = null;

}
public Node(int v, Node next)
{
this.v = v;
this.next = next;
1
2
3 4
5
a

d

b

c

G2
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 17

}
}
class Program
{
static int m, n, v0;
static Node t;
static Node[] ke ;
static int []dinh;
static bool[] chuaxet;

public static void readF()
{
int x, y;
StreamReader read = new StreamReader("dsk2.txt");
string line = read.ReadLine();
string[] xaucon = new string[2];
xaucon = line.Split(' ');
m = int.Parse(xaucon[0]);
n = int.Parse(xaucon[1]);
ke = new Node [n + 1];
dinh = new int[n + 1];
chuaxet = new bool[n+1];
khoitao();
line = read.ReadLine();
while (line != null)
{
xaucon = line.Split();
x = int.Parse(xaucon[0]);
y = int.Parse(xaucon[1]);
t = new Node(x, ke[y]);
ke[y] = t;
t = new Node(y, ke[x]);
ke[x] = t;
line = read.ReadLine();
}
read.Close();
}
static void khoitao()
{
for (int i = 1; i <= n; i++)

{
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 18

ke[i] = null;
chuaxet[i] = true;
}
}
public static void Hamilton(int k)
{
Node p = new Node();
p = ke[dinh[k - 1]];
while(p != null)
{
if ((k == n + 1) && (p.v == v0))
HienThi();
else
if (chuaxet[p.v])
{
dinh[k] = p.v;
chuaxet[p.v] = false;
Hamilton(k+1);
chuaxet[p.v] = true;
}
p = p.next;
}
}
static void HienThi()
{
for (int i = 1; i <= n; i++)

{
Console.Write(dinh[i] + " ");
}
Console.WriteLine(v0);
Console.WriteLine();
}
static void Main(string[] args)
{
readF();
Console.Write("Nhap vao dinh xuat phat v0 = ");
v0 = int.Parse(Console.ReadLine());
Console.WriteLine();
dinh[1] = v0;
chuaxet[v0] = false;
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 19

Console.WriteLine("Cac chu trinh trong do thi la:");
Console.WriteLine();
Hamilton(2);
Console.ReadKey();
}
}
}

d. Bài tập tự giải
Bài tập 1 ðồ thị sau có là ñồ thị nửa Hamilton hay ñồ thị Hamilton không? Chỉ ra chu trình
Hamilton (ñường Hamilton) nếu có

Bài tập 2 Cho trước N con cờ domino, hãy viết chương trình cho biết rằng có cách sắp N

con cờ ñó theo ñúng luật domino sao cho các con cờ hình thành vòng tròn hay không, nếu
có hãy chỉ ra một cách sắp. Cài ñặt chương trình.
Bài tập 3 Tổng thư ký ðại hội ñồng Liên hợp quốc triệu tập một cuộc họp có N nhà ngoại
giao của N tổ chức tham gia. Các ñại diện ngoại giao ñược bố trí ngồi quanh một bàn tròn.
Giữa một số tổ chức có quan hệ căng thẳng, vì vậy không thể xếp họ ngồi cạnh nhau ñược.
Thông tin về quan hệ giữa các tổ chức ñược cho dưới dạng cặp số nguyên i, j nếu giữa 2 tổ
chức này có quan hệ căng thẳng. Hãy lập trình giúp Tổng thư ký Liên hợp quốc bố trí chỗ
ngồi quanh bàn họp. Các tổ chức ñược ñánh số từ 1 tới N, 0 < N <= 500.
Dữ liệu vào: từ file CONF.INP, dòng ñầu tiên chứa số nguyên N, các dòng sau, mỗi
dòng một cặp số i, j cho biết các ñại diện i và j không ngồi cạnh nhau ñược. Kết thúc là một
dòng chứa 2 số 0.
Kết quả: ñưa ra file CONF.OUT. Nếu không có cách bố trí thỏa mãn yêu cầu thì ñưa
ra thông báo KHONG CO, trong trường hợp ngược lại – ñưa ra dãy N số nguyên xác ñịnh vị
trí ai ngồi cạnh ai quanh bàn tròn.
Bài tập 4 Có 12 người ngồi chung 1 bàn tiệc tròn. Mỗi người có ít nhất 6 người quen. Hãy
chỉ ra cách sắp xếp sao cho mỗi người ñều ngồi cạnh người mình quen . Tổng quát, hãy sắp
N người ngồi chung quanh bàn tròn sao cho mỗi người ñều ngồi cạnh người mình quen.
Biết mỗi người có ít nhất (N + 1)/2 người quen.
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 20

Bài 5 Thảo luận cài ñặt ñồ thị, các thuật toán liệt kê chu trình Euler
và Hamilton.
Mục tiêu
- Lưu trữ ñược ñồ thị trên máy tính theo những phương pháp khác nhau.
- Chuyển ñổi giữa các kiểu biểu diễn ñồ thị trên máy tính.
- Nâng cao khả năng làm việc nhóm.
- Rèn luyện tư duy sáng tạo.
- Phân tích ñược bài toán thực tế tương ứng phần lý thuyết ñã học.
- Sinh viên có khả năng tự học.


Bài 6 Thuật toán tìm kiếm trên ñồ thị và ứng dụng
Mục tiêu
- Trình bày ñược ý tưởng, cách cài ñặt và cài ñặt ñược thuật toán BFS, DFS.
- Nêu ưu nhược của từng thuật toán ñối với từng loại ñồ thị.
- Phân tích ñược bài toán thực tế tương ứng phần lý thuyết ñã học.
- Sinh viên có khả năng tự học.
- Rèn luyện tư duy sáng tạo.
a. Nhắc lại lý thuyết
DFS: Từ một ñỉnh v nào ñó ta bắt ñầu duyệt như sau: ñánh dấu v ñã duyệt, với mỗi ñỉnh w
chưa duyệt kề với v, ta thực hiện ñệ qui quá trình trên cho w. Sở dĩ cách duyệt này có tên là
duyệt theo chiều sâu vì nó sẽ duyệt theo một hướng nào ñó sâu nhất có thể ñược.
BFS: Từ một ñỉnh v nào ñó ta bắt ñầu duyệt như sau: ñánh dấu v ñã ñược duyệt, kế ñến là
duyệt tất cả các ñỉnh kề với v. Khi ta duyệt một ñỉnh v rồi ñến ñỉnh w thì các ñỉnh kề của v
ñược duyệt trước các ñỉnh kề của w.
b. ðề bài tập
Bài 1 Duyệt ñồ thị theo chiều sâu và duyệt theo chiều rộng trên ñồ thị sau (Dùng cây tìm
kiếm ñể từ ñó mô tả kết quả)

Bài 2 Cho ñồ thị G=(V,E). Cài ñặt 2 thuật toán duyệt ñồ thị và ñưa ra thứ tự duyệt.
Bài 3 Cho ñồ thị G=(V,E) với tập các ñỉnh X và tập các cung E. Xét xem ñồ thị có bao
nhiêu thành phần liên thông, mỗi thành phần liên thông bao gồm những ñỉnh nào?

Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 21

c. Hướng dẫn giải
Bài 1
a. Cách 1: Ta dùng cây tìm kiếm ñể mô tả kết quả duyệt chiều sâu và duyệt theo chiều rộng
trên ñồ thị:

Duyệt rộng

Cách 2: Ta dùng hàng ñợi mô tả lại từng bước thuật toán
- ðưa 1 và hàng ñợi.
- Lặp: Lấy từ hàng ñợi ra, duyệt tất cả ñỉnh kề chưa xét ñưa vào hàng ñợi chờ xét
Kết quả theo từng bước của thuật toán duyệt rộng ñược mô tả trong bảng sau:
Trạng thái hàng ñợi ðỉnh ñang duyệt Các ñỉnh ñã duyệt Các ñỉnh chưa
duyệt
1

1 1 2,3,4,5
2 4

2 1,2 3,4,5
4 3 5

4 1,2,4 3,5
3 5 3 5

3 1,2,4,3 5
5 3 5

5 1,2,4,3,5
3 5

3 1,2,4,3,5
5

5 1,2,4,3,5




- Hàng ñợi rỗng thì dừng lại
Ta thu ñược kết quả duyệt rộng sẽ là: 1, 2, 4, 3, 5
Duyệt sâu:


Cách 2: Ta dùng ngăn xếp mô tả lại từng bước thuật toán
- ðưa 1 vào ngăn xếp.
- Lặp: Lấy từ ngăn xếp ra, duyệt tất cả ñỉnh kề chưa xét ñưa vào ngăn xếp chờ xét
Kết quả theo từng bước của thuật toán duyệt sâu ñược mô tả trong bảng sau:
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 22

Trạng thái ngăn
xếp
ðỉnh ñang duyệt Các ñỉnh ñã duyệt Các ñỉnh chưa
duyệt
1

1 1 2,3,4,5
2 4



2 1,2 3,4,5
3

5


4






3 1,2,3 4,5
4

5

4






4 1,2,3,4 5
5 4



5 1,2,4,3,5
4

4 1,2,4,3,5




- Ngăn xếp rỗng thì dừng lại
Ta ñược kết quả như sau: 1, 2, 3, 4, 5
b. Tương tự câu a. Dựa vào ñồ thị xây dựng ñược cây nhị phân tìm kiếm, rồi từ ñó duyệt ñồ
thị ta ñược

Duyệt theo chiều rộng sẽ ñược kết
quả các ñỉnh ñược xét lần lượt như
sau:
S, A, D, B, E, C, F, G
Duyệt theo chiều sâu sẽ ñược kết
quả các ñỉnh ñược xét lần lượt như
sau:
S, A, B, C, E, D, F, G.
Bài 2
Giả sử ñã có các hàm (thủ tục) liên quan tới hàng ñợi và ngăn xếp như sau
public class Queue
{
const int qmax = 1000; //qmax la hang so luu kich thuoc toi da cua hang doi
static int[] q = new int[qmax]; //cai dat hang doi, toi da 1000 ptu
static int qf, ql; //qf: dau hang, ql: cuoi hang
static public void initQ(); //Khoi tao hang doi
static public bool fullQ() ; //Kiem tra day
static public bool emptyQ(); //Kiem tra rong
static public void putQ(int x); //Dua phan tu vao hang doi
static public int getQ(); //lay phan tu tu hang doi ra
}
public class Stack
{
const int Smax = 1000; //qmax la hang so luu kich thuoc toi da cua ngan xep

static int[] S = new int[Smax]; //cai dat ngan xep, toi da 1000 ptu
static int top; //qf: dau hang, ql: cuoi hang
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 23

static public void initS(); //Khoi tao ngan xep
static public bool fullS(); //Kiem tra day
static public bool emptyS(); //Kiem tra rong
static public void pushS(int x); //Dua phan tu vao ngan xep
static public int popS(); //lay phan tu tu ngan xep ra
}
Chương trình minh họa:
using System;
using System.Text;
using System.IO;
namespace LTDT
{
class duyetdothi
{
static string filename = "d:/trr/mtk_b2_t216.in";
static int [,] a; //luu do thi mtran ke
static int xp,n,count;
//dinh xuat phat khi duyet, n la so dinh cua do thi, count dem so thu tu khi duyet
static int[] kq; //luu thhu tu duyet
static bool[] xet; //danh dau xet cho n dinh cua do thi; n la so dinh cua do thi
//doc do thi (BD theo ma tran ke) tu tep txt
static public void doctep(string filename)
//hien thi do thi
static private void hien_dt(int[,] x)
//Duyet do thi => dua ra thu tu duyet

//ten n dinh cua dt la 1,2, n; ta coi nhu ten cac dinh la 0 n-1
static private void init()
{
Console.Write("nhap ten dinh xuat phat: ");
xp = int.Parse(Console.ReadLine());
xp ;
//lay do thi tu tep
doctep(filename);
//danh dau chua xet cho tat ca cac dinh cua do thi
xet = new bool[n];
for (int i = 0; i < n; i++)
xet[i] = false;
kq=new int[n];
count = 0;
}
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 24

static private void BFS()
{
init();
//1. day dinh xp vao Queue, danh dau xet cho dinh xp
Queue.putQ(xp); xet[xp] = true;
kq[count++] = xp;
//cai dat theo thuat toan MR:
//lap qua trinh lay tu Q ra de xet, danh dau xet trc khi day vao Q
do{
int u = Queue.getQ(); //lay u o dau Q , la dinh dg xet
for(int i=0;i<n;i++) //tim tat ca cac dinh i ke u, i chua xet
if (a[u, i] > 0 && xet[i] == false)

{
kq[count++] = i;
xet[i] = true; //danh dau xet cho dinh i, va day i vao Q
Queue.putQ(i);
}
}while (!Queue.emptyQ());
}
static private void DFS()
{
init();
//1. day dinh xp vao Queue, danh dau xet cho dinh xp
Stack.pushS(xp); xet[xp] = true;
kq[count++] = xp;
//cai dat theo thuat toan MR:
//lap qua trinh lay tu Q ra de xet, danh dau xet trc khi day vao Q
do
{
int u = Stack.popS(); //lay u o dau Q , la dinh dg xet
for (int i = 0; i < n; i++) //tim tat ca cac dinh i ke u, va chua xet
if (a[u, i] > 0 && xet[i] == false)
{
kq[count++] = i;
xet[i] = true; //danh dau xet, va day vao Q
Stack.pushS(i);
}
} while (!Stack.emptyS());
}
//ghi thu tu duyet
Bài tập TOÁN RỜI RẠC 2 Bộ môn Công nghệ phần mềm - 2011
Trang 25


static private void ketqua()
{
Console.WriteLine("thu tu duyet thu dc nhu sau:");
for (int i = 0; i < count; i++)
Console.Write("{0}\t",kq[i]+1);
Console.WriteLine();
}
static void menu()
{
int chon;
Console.WriteLine("\n\t nhap 1 de lay do thi BD theo ma tran ke tu tep");
Console.WriteLine("\n \tnhap 2 de duyet do thi theo chieu sau (DFS): ");
Console.WriteLine("\n \tnhap 3 de duyet do thi theo chieu rong (BFS): ");
Console.WriteLine("\n \tnhap 4 de hien thi thu tu duyet dinh xuat phat: ");
Console.WriteLine("\n \tnhap 5 de hien thi thong tin dau vao (do thi va ten
dinh xp): ");
Console.WriteLine("\n \tnhap 0 de thoat: ");
do{
Console.Write(" \tban chon: ");
chon = int.Parse(Console.ReadLine());
switch (chon)
{
case 1: doctep(filename);break;
case 2: DFS(); break;
case 3: BFS(); break;
case 4: ketqua(); break;
case 5: hien_dt(a); break;
}
}while(chon!=0);

}
static void Main()
{
menu();
Console.ReadKey();
}
}
}

×