这题简直就是在虐人。。。无限RE,之后就是无限TEL,NND。。。。最后看的别人的题解才过的。
开一个优先队列pq数组,pq[i]代表这个第i号医生面诊的队列,优先原则就是先到的先看病,一起到的看这个人的编号,编号小的先看,之后用一个普通队列p数组,p[i]代表第i个人要看的医生的集合。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define MAXD 1000 + 100
#define Inf 1 << 30
struct Man{
int t;
int id;
Man(int x = 0 ,int y = 0){
t = x;
id = y;
}
friend bool operator <(Man p,Man q){
if(p.t != q.t){
if(p.t > q.t) return true;
else return false;
}
else {
if(p.id > q.id) return true;
else return false;
}
}
};
int ff[MAXD];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m,k;
queue<int>q[MAXD]; /*第i个人看的医生集合*/
priority_queue<Man>pq[MAXD]; /*表示医生面对的当前病人集合*/
scanf("%d%d",&n,&m);
for(int i = 1; i <= n ; i++){
scanf("%d%d",&ff[i],&k);
while(k--){
int x;
scanf("%d",&x);
q[i].push(x);
}
}
for(int i = 1; i <= n ; i++){
pq[q[i].front()].push(Man(ff[i],i));
q[i].pop();
}
int cur = -1;
int ans = 0;
while(true){
int tmp = Inf;
for(int i = 1; i <= m ;i ++){
if(!pq[i].empty()){
if(pq[i].top().t < tmp){
tmp = pq[i].top().t;
}
}
} /*找出一个时间距离现在最近的*/
if(tmp == Inf) break;
if(tmp > cur) cur = tmp;
else cur ++;
for(int i = 1; i <= m ;i++){
if(!pq[i].empty()){
if(pq[i].top().t <= cur){
ans = cur + 1;
int id = pq[i].top().id;
pq[i].pop();
if(!q[id].empty()){
pq[q[id].front()].push(Man(ans,id));
q[id].pop();
}
}
}
}
}
printf("%d\n",ans);
}
return 0;
}