제출 #1219685

#제출 시각아이디문제언어결과실행 시간메모리
1219685onbertBitaro’s Party (JOI18_bitaro)C++20
0 / 100
2107 ms346648 KiB
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5, sq = 150, INF = 1e9;
int n, m;
vector<int> adj[maxn], radj[maxn];

bool on[maxn];

vector<int> solve() {
    int left[n+1];
    queue<int> q;
    vector<int> ans(n+1);
    for (int i=1;i<=n;i++) {
        left[i] = adj[i].size();
        if (!left[i]) q.push(i);
    }
    while (q.size()) {
        int u = q.front();
        q.pop();
        if (on[u]) ans[u] = 0;
        else ans[u] = -1;
        for (int v:adj[u]) if (ans[v] != -1) ans[u] = max(ans[v] + 1, ans[u]);
        for (int v:radj[u]) {
            left[v]--;
            if (!left[v]) q.push(v);
        }
    }
    return ans;
}

vector<int> ori_ans;

vector<pair<int,int>> vec[maxn];
int mn[maxn];

bool cmp(pair<int,int> x, pair<int,int> y) {
    return mn[x.first] < mn[y.first];
}

void pre() {
    int left[n+1];
    queue<int> q;
    for (int i=1;i<=n;i++) {
        left[i] = adj[i].size();
        if (!left[i]) q.push(i);
    }
    while (q.size()) {
        int u = q.front();
        q.pop();
        vec[u].push_back({u, 0});
        mn[u] = ori_ans[u] + 1;
        for (int v:adj[u]) for (auto [x, y]:vec[v]) mn[x] = INF;
        int sz = adj[u].size();
        for (int v:adj[u]) {
            for (auto [x, y]:vec[v]) {
                mn[x] = min(ori_ans[u] - ori_ans[v] - 1 + y, mn[x]);
                vec[u].push_back({x, 0});
            }
        }
        sort(vec[u].begin(), vec[u].end(), cmp);
        vec[u].erase(unique(vec[u].begin(), vec[u].end()), vec[u].end());
        // while (vec[u].size() > sq) vec[u].pop_back();
        for (auto &[x, y]:vec[u]) y = mn[x];

        for (int v:radj[u]) {
            left[v]--;
            if (!left[v]) q.push(v);
        }
    }
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int q;
    cin >> n >> m >> q;
    for (int i=1;i<=m;i++) {
        int u, v;
        cin >> u >> v;
        radj[u].push_back(v); adj[v].push_back(u);
    }
    for (int i=1;i<=n;i++) on[i] = true;
    ori_ans = solve();
    pre();

    // for (int i=1;i<=n;i++) {
    //     int last = 0;
    //     for (auto [x, y]:vec[i]) {
    //         if (y != last) {
    //             last = y;
    //             assert (solve()[i] == ori_ans[i] - y + 1);
    //         }
    //         on[x] = false;
    //     }
    //     for (auto [x, y]:vec[i]) on[x] = true;
    // }

    while (q--) {
        int u, sz;
        cin >> u >> sz;
        if (!sz) {
            cout << ori_ans[u] << "\n";
            continue;
        }
        vector<int> off(sz);
        for (int &i:off) {
            cin >> i;
            on[i] = false;
        }
        if (sz >= sq || true) cout << solve()[u] << "\n";
        else {
            // cout << u << endl;
            bool flag = true;
            for (auto [x, y]:vec[u]) {
                // cout << x << " " << y << endl;
                if (on[x]) {
                    cout << ori_ans[u] - y + 1 << "\n";
                    flag = false;
                    break;
                }
            }
            if (flag) cout << "-1\n";
        }
        for (int i:off) on[i] = true;
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...