UVA - 10588 Queuing at the doctors (队列)

本文介绍了一个模拟医院排队过程的算法问题。通过设定一系列规则,包括员工的体检顺序、时间安排及医生的工作效率等,该算法能够计算出最后一个员工完成体检所需的时间。采用优先队列进行模拟,有效解决了排队问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Download as PDF

Problem H: Queuing at the doctors

Due to the increasing number of weird viruses spreading around, all the members of the International Confederation of Revolver Enthusiasts (ICORE) are required by their boss to do quarterly physical checkups at General Hospital. All checkups are arranged by the boss and scheduled on the same day. Each member of ICORE gets instructions where they are given
  • their number from the set {1 ... n}
  • the time of the day when they are supposed to show up at General Hospital
  • a list of doctors' offices that they are to visit in the listed order.
Doctors' offices in General Hospital are numbered with numbers from the set {1 ... m}.

All the members of ICORE have been convinced that the schedule of the checkups has been professionally prepared and that there would be no lining up and waiting at the doctors' doors. However, since their boss was a political appointment their hopes for not wasting time had to be abandoned as soon as they started arriving at the hospital. The queues were forming rapidly despite the fact that the doctors were very efficient due to their usual sloppiness. The members of ICORE are all very disciplined and obey the following rules for visiting the doctors

  • if an ICORE member was supposed to show up at the hospital at time t, then at time t they show up at the first doctors' office on their list;
  • if several people show up a doctor's office at time t then they form a queue in increasing order of their numbers and join the end of the queue already formed by people who arrived earlier;
  • if at time t in front of office x there is a queue of people who arrived earlier or at time t, then the first person from the queue enters office x. This person after a time unit (the doctors do a sloppy job, remember) exits the office and at time t+1 appears at the next office from their list of offices to visit. At that time the first person from the queue enters office x;
  • if a visit at office x at time t was for the given visitor the last visit on their list, then at time t+1 this visitor leaves the hospital.

Your task is to find the time when the last visitor leaves the hospital.

The first line of input contains a natural number c giving the number of cases to handle. The following lines form the input for the c cases, each in the format described below. The first line of data for a case contains two natural numbers n and m, 1 ≤ n, m ≤ 1000, giving the number of the visitors and the number of doctors' offices for the case. Each of the following n lines contains a sequence of natural numbers. Among these lines, line i (1  ≤ i ≤ n) has the following format

t   k   g 1   g 2... g k
meaning that the ith visitor arrives at time t and has to visit k offices in the order given by g 1 g 2 ... g k where each g j is a number of doctor's office, 1 ≤  g j ≤  m. We have that 0 ≤  t ≤ 1000000 and there is no more than 1000000 visits scheduled for a day at the hospital.

For each of the c input cases print one line giving the time when the last visitor leaves the hospital.





Sample input

 
2
5 3
1 3 3 2 1
0 7 2 3 1 1 1 1 2
2 1 1
1 2 3 3
4 3 1 1 1
5 10
3 1 6
2 3 3 2 8
2 1 4
2 4 7 9 9 6
0 2 8 7

Output for sample input

12
6
题意:某公司要求每个员工都必须到当地的医院体检,并给每个员工安排了体检的顺序。为了节约等待时间,员工们被要求分时段去体检,但排队仍然是必不可少的。因此,公司制定了下面几条规定:
 
 
  • 员工的编号从1到n。
  • 员工在规定的时间点上一定准时到达医院开始体检。
  • 员工有自己的体检顺序,并且一定按顺序来体检,直到体检完才离开医院。
  • 当有多个员工在同一个时刻到同一个医生那体检时,编号小的优先,其他人按到达的先后顺序和编号大小排队等待。

已经知道每个医生在每单位1的时间内可以检查一个员工,给定所有员工的体检时间和体检顺序,请计算一下最后一个员工离开医院的时间。

一共有N(1 ≤ N ≤ 1000)个员工,M(1 ≤ M ≤ 1000)个医生,所有人总的检查次数不超过1000000次。

思路:每个项目都用一个优先队列模拟,处理一个人后,就将这个人丢到它的下一项目对应的队列中
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1100;

struct node {
	int t, id;
	bool operator <(const node &a) const {
		if (t == a.t)
			return id > a.id;
		return t > a.t;
	}
};
int n, m;
priority_queue<node> p[maxn];
queue<int> q[maxn];

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		int x, num, a;
		node now;
		for (int i = 0; i < n; i++) {
			now.id = i;
			scanf("%d%d", &x, &num);
			while (num--) {
				scanf("%d", &a);
				a--;
				q[i].push(a);
			}
			now.t = x;
			p[q[i].front()].push(now);
		}

		int ans = 0, flag = 1;
		while (flag) {
			flag = 0;
			for (int i = 0; i < m; i++) {
				if (!p[i].empty()) {
					flag = 1;
					now = p[i].top();
					if (now.t > ans)
						continue;
					p[i].pop();
					q[now.id].pop();
					if (!q[now.id].empty()) {
						now.t = ans + 1;
						p[q[now.id].front()].push(now);
					}
				}
			}
			ans++;
		}	
		printf("%d\n", ans-1);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值