1. Trang chủ
  2. » Giáo Dục - Đào Tạo

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

52 395 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 52
Dung lượng 908,38 KB

Nội dung

Dữ liệu ra: hiển thị số thành phần liên thông của đồ thị ra màn hình... 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ỉ

Trang 1

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

Trang 2

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

Trang 3

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

n

i

≤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

Trang 4

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

n

i

≤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”

Trang 5

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 A nxn 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

Trang 6

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 A nxn 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ữ 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

Trang 7

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

n

i

≤1

Dữ liệu ra: In ra màn hình đường đi của người đưa thơ (nếu có)

Trang 8

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

n

i

≤1

Dữ liệu ra: In ra màn hình đường đi của người khách (nếu có)

Trang 9

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ữ 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

Trang 10

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

n

i

≤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ó

Trang 11

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ữ 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

Trang 12

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ữ 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

Trang 13

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

n

i

≤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

Trang 14

#define TenFile "Bai1.inp"

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

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

Trang 15

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

Bac = 0;

for(int j = 0; j<n; j++) if(A[i][j]>0)

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)

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;

Trang 16

}

}

/*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)

cout<<"\n\t So Dinh Bac Chan: "<<Tong;

Trang 17

cout<<"\n\t So Dinh Bac Le: "<<Tong;

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:";

Trang 18

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

n

i

≤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”

Trang 19

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

Trang 20

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];

cout<<"\nDO THI LIEN THONG";

else cout<<"\nDO THI KHONG LIEN THONG";

delete *A;

getch();

}

Trang 21

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 A nxn 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

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

Trang 22

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++)

} while(Dem<n);

return MLT;

}

Trang 23

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 A nxn 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ữ 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

Trang 24

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

Sử dụng kỹ thuật tìm kiếm theo chiều sâu

#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

Trang 25

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

/*Thủ tục đệ quy tìm kiếm đường đi*/

void TimKiem(int SoCanh) {

Trang 26

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

n

i

≤1

Dữ liệu ra: In ra màn hình đường đi của người đưa thơ (nếu có)

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ẻ

Trang 27

Ý 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

¾ 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

#define TenFile "Bai5.inp"

/*Dọc dữ liệu của bài toán*/

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

Trang 28

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];

}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) {

BacDinh++;

Ngày đăng: 21/04/2016, 18:00

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w