zhujiangyuan
2024-11-17 15:55:46
P11289 【MX-S6-T1】「KDOI-11」打印
优先队列简单应用题。10 min 过了。
将文件按照加入时间从小到大排序,对于每一个文件分别去选打印机。
对于打印机,需要选择当前最早能使用的。开一个堆,按照最早可以使用的时间从小到大排序。堆顶为可使用时间最早的打印机。
对于最早可使用的时间小于
处理过后,如果
时间复杂度
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, m;
struct File_ { int s, t, id; } a[N];
bool operator < (File_ a, File_ b) {
return a.t < b.t;
}
struct Print {
LL now, id;
bool operator < (const Print &x) const {
return now > x.now || (now == x.now && id > x.id);
}
};
priority_queue <Print> q, Q;
// q 中存 0 Q 中存非 0
vector <int> ans[N];
signed main () {
ios::sync_with_stdio (false);
cin.tie (0); cout.tie (0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i].s >> a[i].t, a[i].id = i;
sort (a + 1, a + n + 1);
for (int i = 1; i <= m; ++i)
q.push ({0, i});
for (int i = 1; i <= n; ++i) {
if (!Q.empty ()) {
vector <int> v;
while (!Q.empty ()) { // 将 Q 中无需等待的打印机移至 q 中
LL x = Q.top ().now;
if (x > a[i].t) break;
v.push_back (Q.top ().id), Q.pop ();
}
for (auto j : v) q.push ({0, j});
}
int id;
if (!q.empty ()) { // 有无需等待的
id = q.top ().id; q.pop ();
Q.push ({a[i].t + a[i].s, id});
}
else { // 需要等待
id = Q.top ().id;
Q.push ({Q.top ().now + a[i].s, id});
Q.pop ();
}
ans[id].push_back (a[i].id); // 记录答案
}
for (int i = 1; i <= m; ++i) {
cout << ans[i].size () << ' ';
sort (ans[i].begin (), ans[i].end ());
for (auto &j : ans[i]) cout << j << ' ';
cout << '\n';
}
return 0;
}