这题开始纠结了很久,到底该怎么维护每个窗口排队的人数,考虑了优先队列和数组,后来知道了要用set
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N= 2e5 + 5;
struct Data { int arrival, spent; }data[N];
struct Timeline {
ll time; int type, id;
Timeline(ll _time = 0, int _type = 0, int _id = 0) :
time(_time), type(_type), id(_id) {}
// type = 0 for departure, type = 1 for arrival
bool operator < (const Timeline &t) const {
if(time != t.time) return time > t.time;
return type > t.type;
}
};
priority_queue<Timeline> Tl;
struct Queue {
int num, id;
Queue(int _num = 0, int _id = 0) :
num(_num), id(_id) {}
bool operator < (const Queue &t) const {
if(num == t.num) return id < t.id;
return num < t.num;
}
}q[N];
set<Queue> Que;
int T, n, m, Queue_select[N];
ll ans, Last[N];
int main() {
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i)
scanf("%d%d", &data[i].arrival, &data[i].spent);
for(int i = 1; i <= n; ++i)
Tl.push(Timeline(data[i].arrival, 1, i));
Que.clear();
for(int i = 1; i <= m; ++i) {
q[i].num = 0, q[i].id = i;
Que.insert(q[i]);
Last[i] = 0;
}
while(!Tl.empty()) {
auto tl = Tl.top(); Tl.pop();
ll time = tl.time; int type = tl.type, id = tl.id;
if(type == 0) {
int qid = Queue_select[id];
Que.erase(Queue(q[qid].num, q[qid].id));
Que.insert(Queue(--q[qid].num, q[qid].id));
}
else {
auto que = *Que.begin();
int num = que.num, qid = que.id;
Que.erase(que);
Queue_select[id] = qid;
if(num == 0) Last[qid] = time + data[id].spent;
else Last[qid] += data[id].spent;
q[qid].num++; que.num++;
Que.insert(que);
Tl.push(Timeline(Last[qid], 0, id));
}
}
ans = 0;
for(int i = 1; i <= m; ++i) ans = max(ans, Last[i]);
printf("%lld\n", ans);
}
return 0;
}
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using std::max, std::priority_queue, std::pair;
using ll = long long;
const int maxn = 1e6 + 5;
int e[maxn << 3][3], head[maxn << 2], tot = -1;
int dep[maxn << 2], maxdep = 0, n = 0, k = 0, p = 0, s = 0, t = 0;
void addEdge(int u, int v, int w) {
e[++tot][0] = v;
e[tot][1] = head[u];
e[tot][2] = w;
head[u] = tot;
}
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1;
maxdep = max(maxdep, dep[u]);
for (int i = head[u]; ~i; i = e[i][1]) {
if (e[i][0] == fa)
continue;
dfs(e[i][0], u);
}
}
ll dis[maxn << 2];
bool vis[maxn << 2];
void dijkstra() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, false, sizeof(vis));
dis[s] = 0;
priority_queue<pair<ll, int>> pq;
pq.emplace(0, s);
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
if (vis[u])
continue;
vis[u] = true;
for (int i = head[u]; ~i; i = e[i][1]) {
int v = e[i][0], w = e[i][2];
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
pq.emplace(-dis[v], v);
}
}
}
}
void solve() {
memset(head, -1, sizeof(head));
tot = -1, maxdep = 0;
scanf("%d", &n);
int u = 0, v = 0, w = 0;
for (int i = 1; i <= n - 1; ++i) {
scanf("%d %d %d", &u, &v, &w);
addEdge(u, v, w), addEdge(v, u, w);
}
dep[0] = -1;
dfs(1, 0);
scanf("%d %d", &k, &p);
for (int i = 1; i <= n; ++i) {
if (dep[i] != 0)
addEdge(n + 2 * dep[i] - 1, i, p);
if (dep[i] != maxdep)
addEdge(n + 2 * (dep[i] + 1), i, p);
if (dep[i] + k <= maxdep)
addEdge(i, n + 2 * (dep[i] + k) - 1, 0);
if (dep[i] - k >= 0)
addEdge(i, n + 2 * (dep[i] - k + 1), 0);
}
scanf("%d %d", &s, &t);
dijkstra();
printf("%lld\n", dis[t]);
}
int main() {
int T = 0;
scanf("%d", &T);
for (int cas = 1; cas <= T; ++cas)
solve();
return 0;
}