Submission #519285

#TimeUsernameProblemLanguageResultExecution timeMemory
519285derrick20Bitaro’s Party (JOI18_bitaro)Java
7 / 100
2094 ms87476 KiB
/**
 * author: derrick20
 * created: 1/25/22 9:47 PM
 */

import java.io.*;
import java.util.*;

import static java.lang.Math.*;

public class bitaro {
    static FastScanner sc = new FastScanner();
    static PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) {
        int N = sc.nextInt(), M = sc.nextInt(), Q = sc.nextInt();
        adjList = new ArrayDeque[N];
        Arrays.setAll(adjList, i -> new ArrayDeque<>());
        for (int i = 0; i < M; i++) {
            int u = sc.nextInt() - 1;
            int v = sc.nextInt() - 1;
            adjList[v].add(u);
        }
        sqrtN = N + 1; // (int) sqrt(N) / 3;
        dpPaths = new int[N][sqrtN][2];
        vis = new boolean[N];

        seen = new boolean[N];
        seenSet = new int[N];
        maxPath = new int[N];
        for (int u = 0; u < N; u++) {
            if (!vis[u]) {
                vis[u] = true;
                solve(u);
            }
        }
        boolean[] busy = new boolean[N];
        while (Q-->0) {
            int partyHost = sc.nextInt() - 1;
            int busyCount = sc.nextInt();
            int[] busyBeavers = new int[busyCount];
            Arrays.setAll(busyBeavers, i -> sc.nextInt() - 1);
            for (int beaver : busyBeavers) {
                busy[beaver] = true;
            }
            int ans = -1;
            if (busyCount < sqrtN) {
                for (int i = sqrtN - 1; i >= 0; i--) {
                    if (dpPaths[partyHost][i][0] == 0) break;
                    if (!busy[dpPaths[partyHost][i][1]]) {
                        ans = dpPaths[partyHost][i][0];
                        break;
                    }
                }
                if (ans == -1 && !busy[partyHost]) {
                    ans = 0;
                }
            } else {
                dpLarge = new int[N];
                Arrays.fill(dpLarge, -1);
                solveLarge(partyHost, busy);
                ans = dpLarge[partyHost];
            }
            out.println(ans);
            for (int beaver : busyBeavers) {
                busy[beaver] = false;
            }
        }
        out.close();
    }

    static ArrayDeque<Integer>[] adjList;
    static int sqrtN;
    static int[][][] dpPaths;
    static boolean[] vis;
    static int[] dpLarge;

    static void solveLarge(int node, boolean[] busy) {
        if (!busy[node]) {
            dpLarge[node] = 0;
        }
        for (int adj : adjList[node]) {
            solveLarge(adj, busy);
            if (dpLarge[adj] != -1)
                dpLarge[node] = max(dpLarge[node], 1 + dpLarge[adj]);
        }
    }

    static boolean[] seen;
    static int[] seenSet;
    static int[] maxPath;
    static void solve(int node) {
        int deg = adjList[node].size();
        if (deg == 0) return;
        HashMap<Integer, Integer> paths = new HashMap<>();
        int seenSize = 0;
        for (int adj : adjList[node]) {
            if (!vis[adj]) {
                vis[adj] = true;
                solve(adj);
            }
            if (!seen[adj]) {
                seen[adj] = true;
                seenSet[seenSize++] = adj;
            }
            maxPath[adj] = max(1, maxPath[adj]);
//            paths.merge(adj, 1, Integer::max);
            for (int i = sqrtN - 1; i >= 0; i--) {
                int dist = dpPaths[adj][i][0];
                int dest = dpPaths[adj][i][1];
                if (dist == 0) break;
                if (!seen[dest]) {
                    seen[dest] = true;
                    seenSet[seenSize++] = dest;
                }
                maxPath[dest] = max(dist + 1, maxPath[dest]);
//                paths.merge(dpPaths[adj][i][1], dpPaths[adj][i][0] + 1, Integer::max);
            }
        }
        int[][] collectedPaths = new int[deg * sqrtN + deg][2];
        int ptr = 0;
        for (int i = 0; i < seenSize; i++) {
            int dest = seenSet[i];
            collectedPaths[ptr++] = new int[]{maxPath[dest], dest};
            seen[dest] = false;
            maxPath[dest] = 0;
        }
        Arrays.sort(collectedPaths, Comparator.comparingInt(path -> path[0]));
        System.arraycopy(collectedPaths, collectedPaths.length - sqrtN, dpPaths[node], 0, sqrtN);
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        int nextInt() {
            return (int) nextLong();
        }

        long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        double nextDouble() {
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            double cur = nextLong();
            if (c != '.') {
                return neg ? -cur : cur;
            } else {
                double frac = nextLong() / cnt;
                return neg ? -cur - frac : cur + frac;
            }
        }

        String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }

    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }

    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}

Compilation message (stderr)

Note: bitaro.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...