首页 > 代码库 > UVA 10588 - Queuing at the doctors(优先队列)

UVA 10588 - Queuing at the doctors(优先队列)

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;
}