제출 #1349652

#제출 시각아이디문제언어결과실행 시간메모리
1349652boropotoBitaro’s Party (JOI18_bitaro)C++17
14 / 100
2098 ms119464 KiB

#include <bits/stdc++.h>
#define endl '\n'

#pragma GCC optimize("O3", "Ofast", "unroll-loops")
#pragma GCC target("avx2")

const int MAXN = 100000;
const int MAXM = 200000;
const int BLOCK = 140;

struct Item {
    int dist;
    int node;
};

static int n, m, q, x, y;
static int dp[MAXN + 5], mx[MAXN + 5];

static int head[MAXN + 5], to[MAXM + 5], nxt[MAXM + 5], edgeCnt;
static int rhead[MAXN + 5], rto[MAXM + 5], rnxt[MAXM + 5], redgeCnt;

static int valCnt[MAXN + 5];
static int valDist[MAXN + 5][BLOCK + 5];
static int valNode[MAXN + 5][BLOCK + 5];

static int touched[MAXN + 5];
static Item tmp[MAXN + 5];

static bool used[MAXN + 5], banned[MAXN + 5], canReach[MAXN + 5], vis[MAXN + 5];

inline bool cmpItem(const Item &a, const Item &b)
{
    if(a.dist != b.dist) return a.dist > b.dist;
    return a.node > b.node;
}

inline void addEdge(int u, int v)
{
    to[++edgeCnt] = v;
    nxt[edgeCnt] = head[u];
    head[u] = edgeCnt;

    rto[++redgeCnt] = u;
    rnxt[redgeCnt] = rhead[v];
    rhead[v] = redgeCnt;
}

inline void dfss(int node)
{
    used[node] = true;

    for(int e = head[node]; e; e = nxt[e])
    {
        int nxtNode = to[e];
        if(!used[nxtNode]) dfss(nxtNode);

        if(canReach[nxtNode])
        {
            canReach[node] = true;
            dp[node] = std::max(dp[node], dp[nxtNode] + 1);
        }
    }
}

inline void solve1()
{
    for(int i = 1; i <= n; i++)
    {
        used[i] = false;
        banned[i] = false;
        dp[i] = 0;
        canReach[i] = false;
    }

    for(int i = 1; i <= y; i++)
    {
        int a;
        std::cin >> a;
        banned[a] = true;
    }

    canReach[x] = true;

    for(int i = 1; i <= n; i++)
    {
        if(!used[i] && i != x)
        {
            dfss(i);
        }
    }

    int ans = -1;
    for(int i = 1; i <= n; i++)
    {
        if(canReach[i] && !banned[i])
        {
            ans = std::max(ans, dp[i]);
        }
    }

    std::cout << ans << endl;
}

inline void dfs(int node)
{
    vis[node] = true;

    int touchedCnt = 0;
    touched[++touchedCnt] = node;
    mx[node] = 0;

    for(int e = rhead[node]; e; e = rnxt[e])
    {
        int prev = rto[e];
        if(!vis[prev]) dfs(prev);

        for(int j = 1; j <= valCnt[prev]; j++)
        {
            int id = valNode[prev][j];
            int dist = valDist[prev][j] + 1;

            if(mx[id] == -1)
            {
                mx[id] = dist;
                touched[++touchedCnt] = id;
            }
            else if(mx[id] < dist)
            {
                mx[id] = dist;
            }
        }
    }

    for(int i = 1; i <= touchedCnt; i++)
    {
        int id = touched[i];
        tmp[i] = {mx[id], id};
        mx[id] = -1;
    }

    std::sort(tmp + 1, tmp + touchedCnt + 1, cmpItem);

    valCnt[node] = std::min(BLOCK, touchedCnt);
    for(int i = 1; i <= valCnt[node]; i++)
    {
        valDist[node][i] = tmp[i].dist;
        valNode[node][i] = tmp[i].node;
    }
}

inline void solve2()
{
    for(int i = 1; i <= n; i++)
    {
        banned[i] = false;
    }

    for(int i = 1; i <= y; i++)
    {
        int a;
        std::cin >> a;
        banned[a] = true;
    }

    int ptr = 1;
    while(ptr <= valCnt[x] && banned[valNode[x][ptr]])
    {
        ptr++;
    }

    if(ptr > valCnt[x]) std::cout << -1 << endl;
    else std::cout << valDist[x][ptr] << endl;
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> n >> m >> q;
    for(int i = 1; i <= m; i++)
    {
        int u, v;
        std::cin >> u >> v;
        addEdge(u, v);
    }

    std::memset(mx, -1, sizeof(mx));

    for(int i = 1; i <= n; i++)
    {
        if(!vis[i]) dfs(i);
    }

    while(q--)
    {
        std::cin >> x >> y;

        if(y >= BLOCK) solve1();
        else solve2();
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...