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 1BỘ 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 2MỤ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 3MỘ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 4BÀ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 5BÀ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 6BÀ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 7BÀ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 8BÀ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 9BÀ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 10BÀ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 11BÀ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 12BÀ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 13HƯỚ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 15for(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 17cout<<"\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 18BÀ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 19HƯỚ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 20for(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 21BÀ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 22Bướ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 23BÀ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 24HƯỚ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 25DanhDau[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 26BÀ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 28cout<<" "<<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++;