UVA 10588 - Queuing at the doctors
题意:某公司要求每个员工都必须到当地的医院体检,并给每个员工安排了体检的顺序。为了节约等待时间,员工们被要求分时段去体检,但排队仍然是必不可少的。因此,公司制定了下面几条规定:
员工的编号从1到n。
员工在规定的时间点上一定准时到达医院开始体检。
员工有自己的体检顺序,并且一定按顺序来体检,直到体检完才离开医院。
当有多个员工在同一个时刻到同一个医生那体检时,编号小的优先,其他人按到达的先后顺序和编号大小排队等待。
已经知道每个医生在每单位1的时间内可以检查一个员工,给定所有员工的体检时间和体检顺序,请计算一下最后一个员工离开医院的时间。
一共有N(1 ≤ N ≤ 1000)个员工,M(1 ≤ M ≤ 1000)个医生,所有人总的检查次数不超过10000000
思路:直接用队列和优先队列去模拟即可,开m个优先队列,表示每个医生,每次按时间再按标号做优先级。这题我一开始是把每个人对应看医生的序列一起丢进优先队列中,结果超时了,改了这个地方就过了
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 1005;
int T, n, m;
struct Person {
int t, id;
bool operator < (const Person& c) const {
if (t != c.t) return t > c.t;
return id > c.id;
}
} p;
priority_queue<Person> Q[N];
queue<int> q[N];
void init() {
scanf("%d%d", &n, &m);
int k, num;
for (int i = 0; i < n; i++) {
p.id = i;
scanf("%d%d", &p.t, &k);
for (int j = 0; j < k; j++) {
scanf("%d", &num);
num--;
q[p.id].push(num);
}
Q[q[p.id].front()].push(p);
}
}
int solve() {
int flag = 1, ans = 0;
while (flag) {
flag = 0;
for (int i = 0; i < m; i++) {
if (!Q[i].empty()) {
flag = 1;
Person now = Q[i].top();
if (ans < now.t) continue;
Q[i].pop();
q[now.id].pop();
if (!q[now.id].empty()) {
now.t = ans + 1;
Q[q[now.id].front()].push(now);
}
}
}
ans++;
}
return ans - 1;
}
int main() {
scanf("%d", &T);
while (T--) {
init();
printf("%d\n", solve());
}
return 0;
}