JOI 2019 - Two Transportations
Xem PDFNước JOI có \(N\) thành phố, đánh số từ \(0\) đến \(N-1\). Có \(A\) tuyến đường sắt, đánh số từ \(0\) đến \(A-1\). Tuyến thứ \(i\) nối hai chiều giữa \(U_i\) và \(V_i\), với giá vé \(C_i\). Các tuyến đường sắt nối các cặp thành phố khác nhau.
Cũng có \(B\) tuyến xe buýt, đánh số từ \(0\) đến \(B-1\). Tuyến thứ \(j\) nối hai chiều giữa \(S_j\) và \(T_j\), với giá vé \(D_j\). Các tuyến xe buýt nối các cặp thành phố khác nhau. Một tuyến đường sắt và một tuyến xe buýt có thể nối cùng một cặp thành phố. Có thể đi giữa bất kỳ hai thành phố nào bằng đường sắt và/hoặc xe buýt.
Azer muốn biết tổng giá vé nhỏ nhất để đi từ thành phố \(0\) đến từng thành phố. Azer chỉ biết các tuyến đường sắt, còn Baijan chỉ biết các tuyến xe buýt. Hai người trao đổi các ký tự 0 hoặc 1, với tổng số ký tự cả hai gửi không quá \(58\,000\).
Hãy cài đặt chương trình cho cả Azer và Baijan để sau khi trao đổi, Azer tìm được các giá trị cần thiết.
Giao diện tương tác
Nộp một tệp C++ cài đặt cả hai phần Azer và Baijan, khai báo #include "transportations.h". Không cài đặt hàm main. Phần Azer gồm các hàm:
void InitA(int N, int A, std::vector<int> U, std::vector<int> V,
std::vector<int> C);
void ReceiveA(bool x);
std::vector<int> Answer();
InitAđược gọi đúng một lần lúc bắt đầu. \(N\) là số thành phố, \(A\) là số tuyến đường sắt. Các mảngU,V,Ccó độ dài \(A\), mô tả hai đầu mút và giá vé của từng tuyến.ReceiveA(x)được gọi mỗi khi Azer nhận một ký tự từ Baijan;truebiểu diễn1,falsebiểu diễn0.Answer()được gọi đúng một lần khi tất cả ký tự đã được nhận. Hàm phải trả về mảngZcó độ dài \(N\), nếu không nhậnWrong Answer [1].Z[k]phải là tổng giá vé nhỏ nhất từ thành phố \(0\) đến thành phố \(k\); đặc biệtZ[0] = 0.
Trong phần Azer, có thể gọi hàm do thư viện cung cấp để gửi một ký tự cho Baijan:
void SendA(bool y);
Trong cùng tệp nộp, cài đặt phần Baijan gồm các hàm:
void InitB(int N, int B, std::vector<int> S, std::vector<int> T,
std::vector<int> D);
void ReceiveB(bool y);
InitBđược gọi đúng một lần lúc bắt đầu. \(N\) là số thành phố, \(B\) là số tuyến xe buýt. Các mảngS,T,Dcó độ dài \(B\), mô tả hai đầu mút và giá vé của từng tuyến.ReceiveB(y)được gọi mỗi khi Baijan nhận một ký tự từ Azer;truebiểu diễn1,falsebiểu diễn0.
Trong phần Baijan, có thể gọi hàm do thư viện cung cấp để gửi một ký tự cho Azer:
void SendB(bool x);
Thứ tự trao đổi
Với mỗi test, trình chấm tạo hai hàng đợi: \(Q_Y\) chứa các ký tự Azer gửi và \(Q_X\) chứa các ký tự Baijan gửi. Trước tiên, gọi InitA, rồi InitB; các ký tự gửi trong hai hàm này được đưa vào hàng đợi tương ứng.
- Nếu ít nhất một hàng đợi không rỗng, lấy một ký tự ở đầu hàng đợi đó và gọi
ReceiveAhoặcReceiveBtương ứng. Nếu cả hai hàng đợi đều không rỗng, không quy định bên nào được nhận trước. - Khi
SendAđược gọi trongReceiveA, ký tự gửi được đưa vào \(Q_Y\). - Khi
SendBđược gọi trongReceiveB, ký tự gửi được đưa vào \(Q_X\). - Khi cả hai hàng đợi đều rỗng, gọi
Answerrồi kết thúc chương trình.
Tổng số lần gọi SendA và SendB không được vượt quá \(58\,000\), nếu không nhận Wrong Answer [2].
Có thể khai báo biến toàn cục và hàm phụ. Tệp nộp được biên dịch cùng trình chấm thành một tệp thực thi. Nên đặt biến và hàm phụ của hai bên trong các namespace khác nhau để tránh trùng tên, còn các hàm giao diện ở trên phải được khai báo ở phạm vi toàn cục. Đặt các chỉ thị #include ngoài namespace. Khi chấm thực tế, cùng tệp thực thi được chạy thành hai tiến trình riêng cho Azer và Baijan, không chia sẻ biến toàn cục. Tiến trình Azer chỉ nhận dữ liệu đường sắt và được gọi các hàm của Azer; tiến trình Baijan chỉ nhận dữ liệu xe buýt và được gọi các hàm của Baijan.
Không được đọc đầu vào chuẩn, ghi đầu ra chuẩn hoặc giao tiếp với các tệp khác bằng bất kỳ cách nào. Có thể ghi thông tin gỡ lỗi ra đầu ra lỗi chuẩn.
Thư viện thử nghiệm
Gói tệp mẫu chứa transportations.h, transportations.cpp, grader.cpp và README.txt. Tệp README.txt giải thích cách chuyển từ giao diện hai tệp của đề gốc sang giao diện một tệp nộp. Đặt ba tệp mã nguồn và tiêu đề trong cùng thư mục, thay nội dung transportations.cpp bằng lời giải của bạn và biên dịch bằng:
g++ -std=gnu++14 -O2 -o grader grader.cpp transportations.cpp
Trình chấm mẫu chạy trong một tiến trình, khác với trình chấm thực tế.
Dữ liệu vào
Đầu vào của trình chấm mẫu có dạng:
N A B
U_0 V_0 C_0
...
U_{A-1} V_{A-1} C_{A-1}
S_0 T_0 D_0
...
S_{B-1} T_{B-1} D_{B-1}
Nếu \(A=0\) hoặc \(B=0\), phần tương ứng không có dòng nào.
Dữ liệu ra
Theo mô tả trong đề chính thức, trình chấm mẫu ghi loại lỗi Wrong Answer [1] hoặc Wrong Answer [2] ra đầu ra lỗi chuẩn và không ghi gì ra đầu ra chuẩn nếu có lỗi. Nếu không, nó ghi Accepted: L ra đầu ra lỗi chuẩn, trong đó \(L\) là tổng số ký tự đã gửi, và ghi mảng trả về ra đầu ra chuẩn, mỗi phần tử một dòng:
Z[0]
...
Z[N-1]
Trình chấm mẫu không kiểm tra các giá trị trong Z có đúng hay không. Nếu có nhiều loại lỗi, chỉ một loại được báo.
Ràng buộc
- \(1\le N\le2000\).
- \(0\le A,B\le500\,000\).
- \(0\le U_i,V_i\le N-1\) và \(U_i\ne V_i\) với \(0\le i<A\).
- Hai tuyến đường sắt khác nhau không nối cùng một cặp thành phố, kể cả khi đảo thứ tự hai đầu mút.
- \(0\le S_j,T_j\le N-1\) và \(S_j\ne T_j\) với \(0\le j<B\).
- Hai tuyến xe buýt khác nhau không nối cùng một cặp thành phố, kể cả khi đảo thứ tự hai đầu mút.
- Có thể đi giữa mọi cặp thành phố bằng đường sắt và/hoặc xe buýt.
- \(1\le C_i\le500\) với \(0\le i<A\).
- \(1\le D_j\le500\) với \(0\le j<B\).
Phân nhóm
- (6 điểm) \(A=0\).
- (8 điểm) \(B\le1000\).
- (8 điểm) \(A+B=N-1\).
- (38 điểm) \(N\le900\).
- (14 điểm) \(N\le1100\).
- (10 điểm) \(N\le1400\).
- (16 điểm) Không có ràng buộc bổ sung.
Ví dụ giao tiếp
4 3 4
0 1 6
2 1 4
2 0 10
1 2 3
3 1 1
3 2 3
3 0 7
Một chuỗi lời gọi tương ứng:
| Bên gọi | Lời gọi | Giá trị trả về |
|---|---|---|
| Trình chấm | InitA(4, 3, {0,2,2}, {1,1,0}, {6,4,10}) |
|
| Azer | SendA(true) |
|
| Azer | SendA(false) |
|
| Trình chấm | InitB(4, 4, {1,3,3,3}, {2,1,2,0}, {3,1,3,7}) |
|
| Trình chấm | ReceiveB(true) |
|
| Baijan | SendB(true) |
|
| Trình chấm | ReceiveA(true) |
|
| Trình chấm | ReceiveB(false) |
|
| Trình chấm | Answer() |
{0,6,9,7} |
Nguồn
JOI 2018/2019 Spring Training Camp, ngày 2. Đề gốc tiếng Anh, do Japanese Committee for the International Olympiad in Informatics công bố. Bản dịch tiếng Việt theo CC BY-SA 4.0.
Kỳ thi:
- JOI 2019 - Trại huấn luyện, ngày 2 (21 Tháng ba, 2019)
Bình luận