Ôn tập cụ thể
Câu 1
Trong một lớp học có
nsinh viên (giả sử được đánh số từ1tớin). Mỗi sinh viên đều được cấp một tài khoản nên có thể sử dụng tài khoản này để đăng nhập hệ thốngGiả sử không có ai tự gửi email cho chính mình và người
Acó thể gửi cho ngườiBvà nhiềuHãy tìm người đã nhận nhiều email nhất.
💡 GIẢI THÍCH
Cho ví dụ sau:
3
0 1 0
1 0 1
1 2 0
Đầu vào: Có nghĩa là có 3 sinh viên.
0 1 0: SV1 gửi cho SV21email1 0 1: SV2 gửi cho SV1, SV31email1 2 0: SV3 gửi 1emailcho SV1 và gửi2email cho SV2
Đầu ra:
In ra màn hình người đã nhận nhiều email nhất dạng sau: x has received y email(s).
| Input | Result |
|---|---|
| 3 0 1 0 1 0 1 1 2 0 | 2 has received 3 email(s). |
| 7 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 3 has received 2 email(s) |
| 4 0 2 0 0 0 0 1 1 1 1 0 0 1 0 0 0 | 2 has received 3 email(s) |
Phân tích
Đây là 1 đơn đồ thị có hướng và không có khuyên
🚨 CHÚ Ý
Các bạn có thể làm dễ dàng bằng cách đặt biến mảng, nhưng lập trình là chúng ta phải hiểu luôn cả vấn đề sâu của nó nhé
💡 MẸO
Công việc của ta ngay lúc này chính là chuyển ma trận bằng hàm như sau:
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
int x;
scanf("%d",&x);
if(x != 0)
add_edgeDirection(&G,i,j,x);
}
}
| Ma trận | Đồ thị |
|---|---|
| 0 1 0 1 0 1 1 2 0 | 1 2 1 2 1 1 2 3 1 3 1 1 3 2 2 |

==> Nhìn lên hình và ta cũng có thể đón nhanh được, số 2 nhận 3 email và là nút nhận nhiều nhất.
Tham khảo hàm sau:
int received(Graph G,int x){
int sum = 0;
for(int i = 1; i <= G.n; i++){
if(G.A[i][x] > 0){
sum += G.A[i][x];
}
}
return sum;
}
Lời giải
Câu 2
Công ty ABC có một dự án gồm
ncông việc (giả sử được đánh số từ1tớin). Một công việc thứjcó thể phụ thuộc vào công việc khác, công việc thứi. Khi đó, công việc thứihoàn thành thì mới thực hiện được công việc thứj.Hãy viết chương trình in ra màn hình số lượng công việc phụ thuộc của một công việc
xnào đó.
💡 GIẢI THÍCH
Đầu vào:
Dòng đầu tiên chứa 2 số, tương ứng với số lượng công việc và số lượng mối quan hệ giữa các công việc
Các dòng tiếp theo, mỗi dùng chứa
u,vnói rằng: công việcvphụ thuộc công việcuDòng cuối sẽ chứa công việc
xcần tìm số công việc phụ thuộc
| Input | Result |
|---|---|
| 3 2 1 2 2 3 2 | 2:1 |
| 3 2 1 2 2 3 1 | 1:0 |
| 5 7 1 4 1 2 1 3 1 5 2 3 3 5 4 5 2 | 2:1 |
| 5 7 1 4 1 2 1 3 1 5 2 3 3 5 4 5 5 | 5:3 |
Phân tích
💡 MẸO
Nhìn sơ qua không khác gì bài 1, chúng ta hoàn toàn có thể sử dụng lại:
Ví dụ mô hình 3 và 4:

ở nút số 2 có 1 phụ thuộc ==>
2:1ở nút số 5 có 3 phụ thuộc ==>
5:3
Lời giải
Câu 3
Trang trại vừa nhập về
ncon gà mới và đang chuẩn bị phân bổ vào 2 chuồng gà trống. Tuy nhiên, một số con gà lại không thích ở chung với nhau. Nếu thả chúng vào chung một chuồng thì chúng sẽ mổ nhau.Hãy viết chương trình xem có thể phân chia các con gà vào 2 chuồng gà không, và mỗi chuồng gà có bao nhiêu con.
💡 GIẢI THÍCH
Đầu vào:
Dòng đầu tiên chứa 2 số tương ứng với
số con gàvàcặp gà không thích nhauCác dòng tiếp theo, mỗi dòng chứa gà
avàbsẽ cắn nhau theo chung một chuồng
Đầu ra:
xlà số con gà trong chuồngAylà số con gà trong chuồngB
| Input | Result |
|---|---|
| 5 5 1 3 2 3 2 4 3 5 4 5 | 3 2 |
| 5 4 1 4 5 2 3 2 1 2 | 3 2 |
| 3 3 1 2 2 3 3 1 | -1 -1 |
⚠️ LƯU Ý
Nếu không thể phân chia thì in ra -1 -1
Phân tích
Đầu tiên chúng ta cần xác định bằng cách lấy một ví dụ không quá dễ cũng không quá khó để vẽ ra một mô hình:
Mình sẽ lấy ví dụ
1:==> Nhìn sơ ta cũng biến đáp án là:
Chuồng A Chuồng B 1
2
53
4
💡 MẸO
Vậy thì mình thử sử dụng BFS để duyệt tuần tự: 1 3 2 5 4
B1: Tạo ra 2 danh sách
AvàBB2: bỏ số 1 vào danh sách
AB3: Duyệt từ số tiếp theo tới cuối
B4: Ví dụ là
3, sẽ kiểm tra các đỉnh kề của3có nằm trong danh sáchAkhông ?Nếu vừa có trong
AvàBthì in ra-1 -1và kết thúcNếu có trong danh sách
Athì hãy thêm vào danh sáchBnếu không có trong danh sách
Athì hãy thêm vào danh sáchA
B5: Số phần tử trong 2 danh sách
AvàBlà kết quả
Lời giải
Câu 4
Quốc gia Peaceful và Savage đang chiến tranh. Quân đội của Peaceful tại thành phố
1cần phải vận chuyển vũ khí qua thành phốncần được bảo vệ. Các tuyến đường đi qua thành phố phải đi qua những tuyến đường trung gian, hơn nữa mỗi tuyến đường đều có trọng tải tối đa khác nhau.Hãy viết chương trình kiểm tra sau đó vận chuyển vũ khí từ thành phố
1sang thành phốncó phù hợp hay không
💡 GIẢI THÍCH
Đầu vào:
Dòng dòng đầu tiên chứa
nthành phố vàmtuyến đườngmdòng tiếp theo là danh sách các tuyến đường gồm :u,v,x,y, cho biết tuyến đường từuđếnv, trọng tải cho phép làxvà trọng tải thực tế lày
Đầu ra:
Nếu trọng lượng thực tế vận chuyển đường hợp lý và không bị mất hàng thì in
good planNếu trọng lượng thực tế vận chuyển đường không hợp lý hoặc bị mất hàng thì in
bad plan
VÍ DỤ:
| Input | Output |
|---|---|
| 7 10 1 2 9 3 1 3 4 4 1 4 8 2 2 3 4 1 2 6 3 3 3 7 7 4 4 5 5 2 5 3 3 0 5 7 2 2 6 7 6 3 | bad plan |
| 7 10 1 2 9 5 1 3 4 4 1 4 8 2 2 3 4 0 2 6 3 3 3 7 7 4 4 5 5 2 5 3 3 0 5 7 2 2 6 7 6 3 | bad plan |
| 7 10 1 2 9 3 1 3 4 4 1 4 8 2 2 3 0 4 2 6 3 3 3 7 7 4 4 5 5 2 5 3 3 0 5 7 2 2 6 7 6 3 | bad plan |
| 7 10 1 2 9 3 1 3 4 4 1 4 8 2 2 3 4 0 2 6 3 3 3 7 7 4 4 5 5 2 5 3 3 0 5 7 2 2 6 7 6 3 | good plan |
Phân tích
Chúng ta sẽ lấy ví dụ đúng và sai (cụ thể là ví dụ là 1 và 4)
| Mô hình 1 | Mô hình 4 |
|---|---|
![]() | ![]() |
⚠️ LƯU Ý
Hãy nhìn mô hình 1 ở nút số 2 : vào 3 nhưng lại ra 3+1 = 4 ==> Sai (check các trường hợp còn lại)
Ở mô hình 4 tổng vào và tổng ra đều là 2+4+3 và các nút còn lại cũng luồng ra và luồng vào như sau
💡 MẸO
B1: Nhập cung nhưng kiểm tra trọng tải
Nếu sai thì in ra
bad planvàreturn 0B2: Kiểm tra luồng vào của nút
nvà luồng ra của nút1Nếu không bằng nhau thì in ra
bad planvàreturn 0B3: Kiểm tra luồng vào và ra của các nút còn lại
Nếu có nút nào luồng vào và ra không bằng nhau thì in ra
bad planvàreturn 0B4: In ra
good plankhi các trường hợp trên sai
Lời giải
Câu 5
John là lập trình viên sống tại San Francisco. Hiện tại trong nhóm phát triển phần mềm với 2 công ty
AvàB. Vì lý do đặc biệt nên hàng thángJohnphải đi qua lại công tyAvàB.Biết rằng tại nơi
Johnsống có thể đi đến công tyAvàBthông qua hệ thống các chuyến bay như sau:
STT Chuyến bay Giá vé 1 San Francisco <=> Detroit $329 2 San Francisco <=> New York $359 3 San Francisco <=> Denver $279 4 San Francisco <=> Los Angeles $69 5 Denver <=> Los Angeles $209 6 Denver <=> Detroit $129 7 Denver <=> New York $279 8 Los Angeles <=> New York $379 9 Los Angeles <=> Detroit $349 10 Detroit <=> New York $89 Ví dụ vé số
1là từ SanFranciscotớiDetroitvàDetroittớiFranciscođề có giá vé là$329Để đơn giản ta sẽ đánh các thành phố theo số sau:
San Francisco Detroit New York Los Angeles Denver 1 2 3 4 5 Thông thường thì chuyến bay của
Johnsẽ đến gặp công tyAvàBdiễn ra trong3ngày:
Ngày
1: Đi từ nhà (San Francisco) tới công tyA(Denver)Ngày
2: Đi từ công tyA(Denver) tới công tyB(New York)Ngày
3: Đi từ công tyB(New York) về nhà (San Francisco)Viết chương trình giúp
Johnchọn chuyến bay sau cho chi phí phải trả là thấp nhất
💡 GIẢI THÍCH
Đầu vào:
Dòng đầu tiên chứa
số thành phốvàsố chuyến bay giữa 2 thành phốCác Dòng tiếp theo chứa 3 số
u,v,w: chuyến bay từutớivcó giáwDòng cuối chứa
xvàylà hai thành phố vàJohnmuốn tìm đường đi công tác với số tiền thấp nhất
| Input | Result |
|---|---|
| 5 10 1 2 329 1 3 359 1 5 279 1 4 69 5 4 209 5 2 129 5 3 279 4 3 379 4 2 349 2 3 89 1 5 | 278 1 4 5 |
| 5 10 1 2 329 1 3 359 1 5 279 1 4 69 5 4 209 5 2 129 5 3 279 4 3 379 4 2 349 2 3 89 5 3 | 218 5 2 3 |
Phân tích
Từ ví dụ trên ta sẽ có mô hình như sau:

Từ đây chúng ta có thể nhìn đơn giản rằng :
Con đường đi từ
1tới5là :1-4-5và có giá trị là278Con đường đi từ
5tới3là :5-2-3và có giá trị là218
💡 MẸO
Sử dụng giải thuật Dijstra để tìm ra đường đi ngắn nhất
Lời giải
Câu 6
Một người nông dân trồng thanh long cần lắp đèn chiếu sáng vào ban đêm đã cắm n cọc lắp đèn chiếu sáng (được đánh số từ 1 tới n) và bác đã kéo dây điện từ nhà của bác tới cọc số 1.
Trên mỗi cọc này, từ một bóng đèn sẽ nối dây điện cho tất cả bóng đèn ở những cọc còn lại. Nếu một cọc được cấp điện thì tất cả các cọc khác nối với nó cũng được cấp điện, các điểm nối phải nằm trên cọc nào đó (không nằm ở lưng chừng giữa 2 cọc).
Bác nông dân đã thấy có m cặp cọc có thể được nối với nhau và đã ghi lại chiều dài dây điện cần thiết để nối (mỗi dây kết nối có giá tiền khác nhau).
Hãy viết chương trình giúp nông dân tính số tiền tối thiểu cần để mua dậy điện thắp sáng mảnh vườn thanh long.
💡 GIẢI THÍCH
Đầu vào:
Dòng đầu tiên chứa
số cọc lắp đènvàsố cặp cọc có thể nối với nhau bằng dây điệnCác dòng tiếp theo mỗi dòng sẽ chứa 4 số
u,v,x,ynói rằng : cọcuvới cọcv, cần muaxmét dây mỗi mét có giáynghìn VND/m
Đầu ra:
- In ra màn hình số tiền thấp nhất để mua đèn thắp sáng cả vườn thanh long
⚠️ Nếu bài toán không có lời giải hãy in ra: "KHONG CO LOI GIAI"
| Input | Result |
|---|---|
| 7 10 1 3 5 2 1 2 2 3 1 4 7 2 3 2 2 2 3 5 8 1 2 4 1 3 2 6 9 4 4 7 10 2 5 6 6 5 6 7 15 2 | 71 |
| 7 7 1 3 5 4 1 2 2 2 1 4 7 2 3 2 2 5 2 4 1 4 2 6 9 5 5 7 8 6 | KHONG CO LOI GIAI |
| 5 8 1 2 7 2 1 3 10 3 2 3 8 2 2 4 2 3 2 5 9 2 3 4 6 3 3 5 15 2 4 5 7 3 | 54 |
Phân tích
Đầu tiên về phần nhập giá trị: 2 thông số x và y thực chất ta có thể gộp lại bằng phép nhân như sau:
| Ban đầu | Gộp lại | Mô hình |
|---|---|---|
| 1 3 5 2 1 2 2 3 1 4 7 2 3 2 2 2 3 5 8 1 2 4 1 3 2 6 9 4 4 7 10 2 5 6 6 5 6 7 15 2 | 1 3 10 1 2 6 1 4 14 3 2 4 3 5 8 2 4 3 2 6 36 4 7 20 5 6 30 6 7 30 | ![]() |
| 1 3 5 4 1 2 2 2 1 4 7 2 3 2 2 5 2 4 1 4 2 6 9 5 5 7 8 6 | 1 3 20 1 2 4 1 4 14 3 2 10 2 4 4 2 6 45 5 7 48 | ![]() |
| 1 2 7 2 1 3 10 3 2 3 8 2 2 4 2 3 2 5 9 2 3 4 6 3 3 5 15 2 4 5 7 3 | 1 2 14 1 3 13 2 3 16 2 4 6 2 5 18 3 4 18 3 5 30 4 5 21 | ![]() |
🚨 CHÚ Ý
Bạn hãy chú ý mô hình số 2, nhánh 5-7 nó nằm ngoài chứng tỏ nó không liên thông, nên chúng ta không có lời giải
CÁC BƯỚC LÀM
Bước 1: Nhập vào đồ thị có trọng số
Sử dụng đồ thị
danh sách cungint n,m; scanf("%d%d",&n,&m); initGraph(&G, n); for(int i = 0; i < m; i++){ int x,y,a,b; scanf("%d%d%d%d",&x,&y,&a,&b); int z = a * b; addEdge(&G,x,y,z); }Bước 2: Sử dụng hàm tính cây khung nhỏ nhất kruskal để tìm ra giá trị cây khung nhỏ nhất có trọng số
Bước 3: Kiểm tra đồ thị có liên thông không ? tham khảo
Nếu có: in ra kết quả
Nếu không: in
KHONG CO LOI GIAI






