題目
It's H University's Registration Day for new students. There are M offices in H University, numbered from 1 to M. Students need to visit some of them in a certain order to finish their registration procedures. The offices are in different places. So it takes K units of time to move from one office to another.
There is only one teacher in each office. It takes him/her some time to finish one student's procedure. For different students this time may vary. At the same time the teacher can only serve one student so some students may need to wait outside until the teacher is available. Students who arrived at the office earlier will be served earlier. If multiple students arrived at the same time they will be served in ascending order by student number.
N new students need to finish his/her registration. They are numbered from 1 to N. The ith student's student number is Si. He will be arrived at H University's gate at time Ti. He needs to visit Pi offices in sequence which are Oi,1, Oi,2, ... Oi,Pi. It takes him Wi,1, Wi,2, ... Wi,Pi units of time to finish the procedure in respective offices. It also takes him K units of time to move from the gate to the first office.
For each student can you tell when his registration will be finished?
N個新生入學,每個新生需要到M個office中的某些去辦理手續,從一個office到另一個office路上需要花費時間K,第i個新生需要到p[i]個office辦理手續(這p[i]個office分別為 o1, w1, o2, w2 ... o(p[i]), w(p[i]) 其中o為office,w為該新生在該office中辦理手續需要花費的時間)。
如果某個office正在辦理別的同學的手續,則新到的同學需要在門口等待,如果兩個同學同時到達office,則學號低的同學優先。
求出這N個同學各自的手續辦理完成時間。
輸入
The first line contains 3 integers, N, M and K. (1 <= N <= 10000, 1 <= M <= 100, 1 <= K <= 1000)
The following N lines each describe a student.
For each line the first three integers are Si, Ti and Pi. Then following Pi pairs of integers: Oi,1, Wi,1, Oi,2, Wi,2, ... Oi,Pi, Wi,Pi. (1 <= Si <= 2000000000, 1 <= Ti <= 10000, 1 <= Pi <= M, 1 <= Oi,j <= M, 1 <= Wi,j <= 1000)
輸出
For each student output the time when he finished the registration.
解法
參考討論區別人的做法,將學生student進入office記為一個事件,且記錄student到達office的時間,以及該student在該office中辦理手續需要花費的時間。
struct Event{ int student; int office; int begin; int duration; }
用優先隊列維護一個個事件,這樣事件就會按照時間排序,同時各個office接待同學是並行的關系,因此需要對每個office都維護該office可以接待新的同學的最早時間。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string> #include<iostream> #include<algorithm> #include<functional> #include<queue> #include<vector> #include<set> #include<list> #include<unordered_map> #include<unordered_set> #include<stack> #include<map> #include<algorithm> #include<string.h> using namespace std; int N, M, K; struct Student{ int id; int arrive_time; int office_num; int finish_time; vector<pair<int, int>> register_offices; }; Student students[10005]; struct Event{ int student_idx; int office; int begin; int duration; Event(int s, int o, int b, int d) :student_idx(s), office(o), begin(b), duration(d){}; }; struct Cmp{ bool operator()(const Event& e1, const Event& e2){ if (e1.begin == e2.begin) return students[e1.student_idx].id > students[e2.student_idx].id; return e1.begin > e2.begin; } }; priority_queue<Event, vector<Event>, Cmp> pq; int pre[105]; int pos[10005]; void Solve(){ for (int i = 0; i < N; i++){ pq.push(Event(i, students[i].register_offices[0].first, students[i].arrive_time + K, students[i].register_offices[0].second)); pos[i] = 1; } memset(pre, -1, sizeof(pre)); while (!pq.empty()){ Event e = pq.top(); pq.pop(); int st = e.student_idx; if (pre[e.office] > e.begin){ e.begin = pre[e.office]; } int finish_time = e.begin + e.duration; if (pos[st] == students[st].office_num){ students[st].finish_time = finish_time; } else{ int office = students[st].register_offices[pos[st]].first; int duration = students[st].register_offices[pos[st]].second; pq.push({ st, office, finish_time + K, duration }); pos[st] ++; } pre[e.office] = finish_time; } } int main(){ scanf("%d %d %d", &N, &M, &K); int p, o, w; for (int i = 0; i < N; i++){ scanf("%d %d %d", &students[i].id, &students[i].arrive_time, &p); students[i].office_num = p; for (int j = 0; j < p; j++){ scanf("%d %d", &o, &w); students[i].register_offices.push_back({ o, w }); } } Solve(); for (int i = 0; i < N; i++){ printf("%d\n", students[i].finish_time); } return 0; }