You are on page 1of 2

Bài 9: Hệ thống xe buýt.

Busway.pas
Một hệ thống các xe buýt có nhiệm vụ chuyên chở hành khách đi lại giữa một số ga sao
cho đảm bảo tính liên thông hai chiều giữa các ga này. Hệ thống bao gồm một số tuyến
đường, mỗi tuyến đường gồm một số ga khác nhau theo thứ tự mà xe buýt đi qua. Xe
buýt thuộc tuyến đường nào chỉ chạy trên tuyến đường đó, lần lượt qua các ga thuộc
tuyến cho đến hết, sau đó lại quay đầu chạy theo hướng ngược lại. Có thể có một số ga
chung cho một số tuyến đường. Một hành khách muốn đi từ ga đầu đến ga cuối, có thể đi
trên một tuyến hoặc phải chuyển tuyến một số lần ở những nơi có ga chung. Bài toán đặt
ra là, cần tìm một hành trình cho phép đi từ ga đầu đến ga cuối sao cho số lần phải
chuyển tuyến là ít nhất. Nếu tồn tại nhiều phương án như vậy, hãy tìm phương án đi qua
ít ga nhất.
Dữ liệu: busway.inp
 Dòng đầu là số tuyến đường.
 Các dòng tiếp mỗi dòng mô tả một tuyến đường, gồm một chuỗi các kí tự viết liền
nhau, mỗi kí tự mô tả một tên ga theo đúng thứ tự các ga tren tuyến (chú ý các ga
trên cùng một tuyến là khác nhau, nhưng các ga trên các tuyến khác nhau có thể
trùng nhau, tên ga có thể là một kí tự bất kì hiển thị được trong bảng mã ACSII)
 Dòng tiếp theo là số hành trình cần tìm.
 Các dòng tiếp theo, mỗi dòng mô tả một hành trình cần tìm, gồm cặp kí tự viết
liền nhau, xác định các tên ga đầu và ga cuối.
Giả thiết các dữ liệu là hợp lệ, không cần kiểm tra. Giới hạn kích thước 100 cho số
các tuyên đường và 50 cho số các ga trên cùng một tuyến đường.
Kết quả: busway.out
 Mỗi hành trình được viết trên một dòng, gồm các kí tự biểu diễn tên ga viết theo
thứ tự đi được. Các tên ga này được viết thành từng nhóm theo tuyến đường: nếu
thuộc cùng một tuyến thì viết liền nhau, nếu sang tuyến khác thì viết cách nhau
một dấu cách (space), tên ga chung được viết lặp lại.
Ví dụ

Busway.inp Busway.out
3 HEA ABC
ABC GA AB
DBE
GAEH
2
HC
GB

Hướng dẫn:
 Xây dựng đồ thị đường đi giữa các ga là ma trận hai chiều (lưu vào mảng trọng số
a). Coi mỗi kí tự là một đỉnh của đồ thị (dùng hàm ord(kítự) lấy giá trị là số).
a[i,j] = 0 nếu các kí tự “chr(i)”, “ chr(j)” (cũng là các ga) không thuộc cùng một
tuyến đường nào cả. a[i,j] > 0 và là giá trị nhỏ nhất của đoạn đường đi giữa hai ga
(chr(i), chr(j)).
 Dùng thuật toán Dijstra để tìm đường đi ngắn nhất từ ga đầu tới ga cuối. Trong
thuật toán ta có hai ưu tiên sau:
o Số ga giữa đường đi là ít nhất (ưu tiên cao nhất).
o Tổng đường đi giữa các ga là nhỏ nhất.
 Với ưu tiên thứ nhất ta có thể coi đồ thị vừa lập là một đồ thị mới: đồ thị quan hệ:
a[i,j] = 0 tức không có đường đi từ i tới j và a[i,j] > 0 tức có đường đi giữa i và j.
Với ưu tiên thứ nhất ta coi a[i,j] > 0 thì a[i,j] = 1 trong đồ thị mới lập.
 Khi ưu tiên thứ nhất được thoả mãn ta xét đến ưu tiên thứ hai, khi đó coi như
thuật toán Dijstra dùng cho đồ thị cũ đã lập lúc đầu - đồ thị trọng số.
Cấu trúc chương trình:

Procedure Dijstra(s, t: string);


Begin
Fillchar(d, sizeof(d), 0); {luu duong di voi so dinh min}
Fillchar(d1, sizeof(d1), 0); {luu duong di voi tong min khi sdinh min}
Fillchar(chuaxet, sizeof(chuaxet), 1);
Chuaxet[s] = false;
Voi moi i : neu a[s,i] > 0 thi: d[i] = 1; tr[i] = s; d1[i] = a[s,i]
Repeat
u := 0; min := maxint;
for v := dau to n do
if (chuaxet[v])and(d[v]<>0) and (min > d[v]) then
begin u := v; min := d[v]; end;
if u = 0 then exit;
chuaxet[u] := false;
for v := dau to n do
if chuaxet[v] and (a[u,v] > 0) then
if (d[v] = 0) or (d[v] > d[u] + 1) then {uu tien thu nhat}
begin
d[v] := d[u] + 1;
d1[v] := d1[u] + a[u,v];
tr[v] := u;
end
else
if d[v] = d[u] + 1 then
if d1[v] > d1[u] + a[u,v] then {uu tien thu hai}
begin
d1[v] := d1[u] + a[u,v];
tr[v] := u;
end;
until not chuaxet[t];
end;

You might also like