某岛

… : "…アッカリ~ン . .. . " .. .
June 9, 2023

Luogu P1954. [NOI2010] 航空管制

第一问显然可以 dag dp,求出每个点的真实最晚发车时间,
然后用这个东西贪心构造。

第二问还是用同一个 dp 数组,不过这次贪心构造的时候,我们忽略所有询问点传递闭包里的节点。

#include <lastweapon/io>
using namespace lastweapon;

const int N = int(2e3)+9;

VI adj[N], rdj[N]; int f[N], k[N], o[N];
bool vis[N];
int n, m;


void dfs(int u = 0) {
    vis[u] = 1; f[u] = k[u];
    for (auto v: adj[u]) {
        if (!vis[v]) dfs(v);
        checkMin(f[u], (f[v] ? f[v] : k[v]) - 1);
    }
}

void rfs(int u = 0) {
    vis[u] = 1; f[u] = 0;
    for (auto v: rdj[u])  {
        if (!vis[v]) rfs(v);
    }
}

int main() {

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif

    RD(n, m); REP(i, n) RD(k[i]);

    DO(m) {
        int a, b; RD(a, b), a--, b--;
        adj[a].PB(b);
        rdj[b].PB(a);
    }
    REP(i, n) if (!vis[i]) dfs(i); REP(i, n) o[i] = i;

    sort(o, o+n, [](int a, int b) {
         return f[a] < f[b];
    });

    REP(i, n) printf("%d ", o[i]+1); puts("");

    REP(i, n) {
        RST(vis); rfs(i); REP(i, n) if (!vis[i]) dfs(i);

        sort(o, o+n, [](int a, int b) {
            return f[a] > f[b];
        });

        int m = n-1; RST(vis);

        REP(ii, n) {
            int i = o[ii]; if (!f[i]) break;
            int t = min(m, f[i]);
            while (vis[t]) --t; vis[t] = 1;
            while (vis[m]) --m;
        }
        printf("%d ", m+1);
    }
}