「JOISC 2014 Day1」巴士走读

「JOISC 2014 Day1」巴士走读

将询问离线下来。

从终点出发到起点。

由于在每个点(除了终点)的时间被过来的边固定,因此如果一个点不被新的边更新,是不会发生变化的。

因此可以按照时间顺序,依次提高终点的时间,然后跑dijkstra(记得把访问标记回滚清空掉)。

每条边被跑过了就不再跑了。可以用set,也可以vector(排序,记当前在第几条边)

#include <bits/stdc++.h>
#define rep(q, a, b) for (int q = a, q##_end_ = b; q <= q##_end_; ++q)
#define dep(q, a, b) for (int q = a, q##_end_ = b; q >= q##_end_; --q)
#define mem(a, b) memset(a, b, sizeof a)
#define debug(a) cerr << #a << ' ' << a << "___" << endl
using namespace std;
void in(int &r) {
    static char c;
    r = 0;
    while (c = getchar(), !isdigit(c))
        ;
    do
        r = (r << 1) + (r << 3) + (c ^ 48);
    while (c = getchar(), isdigit(c));
}
const int mn = 100005;
const int mm = 300005;
struct edge {
    int s, t, to;
    bool operator<(const edge &A) const { return s == A.s ? (t == A.t ? to < A.to : t < A.t) : s < A.s; }
};
vector<edge> son[mn];
int now_vis[mn], now_lim[mn];
int n, m, Q;
struct node {
    int x, v;
    bool operator<(const node &A) const { return v < A.v; }
};
priority_queue<node> qw;
bool mark[mn];
int d[mn], sta[mn], tp;
void solve(int v) {
    rep(q, 1, tp) mark[sta[q]] = 0;
    tp = 0;
    while (!qw.empty()) qw.pop();
    d[n] = v;
    qw.push({ n, v });
    edge nw;
    while (!qw.empty()) {
        int now = qw.top().x;
        qw.pop();
        if (now == 1)
            return;
        if (mark[now])
            continue;
        sta[++tp] = now;
        mark[now] = 1;
        while (now_vis[now] < now_lim[now]) {
            nw = son[now][now_vis[now]];
            if (nw.s <= d[now]) {
                if (nw.t > d[nw.to]) {
                    d[nw.to] = nw.t;
                    qw.push({ nw.to, nw.t });
                }
                ++now_vis[now];
            } else
                break;
        }
    }
}
struct nd {
    int v, id;
    bool operator<(const nd &A) const { return v < A.v; }
} qr[mn];
int ans[mn];
int main() {
    int a, b, x, y;
    in(n), in(m);
    rep(q, 1, m) in(a), in(b), in(x), in(y), son[b].push_back({ y, x, a });
    rep(q, 1, n) sort(son[q].begin(), son[q].end());
    rep(q, 1, n) now_lim[q] = son[q].size();
    in(Q);
    rep(q, 1, Q) in(qr[q].v), qr[q].id = q;
    sort(qr + 1, qr + Q + 1);
    rep(q, 1, n) d[q] = -1;
    rep(q, 1, Q) {
        solve(qr[q].v);
        ans[qr[q].id] = d[1];
    }
    rep(q, 1, Q) printf("%d
", ans[q]);
    return 0;
}
原文地址:https://www.cnblogs.com/klauralee/p/11305452.html