10pts求助,只a了第二点,玄关
查看原帖
10pts求助,只a了第二点,玄关
1280322
Monte_Cristo楼主2024/3/11 16:29
import java.io.*;
import java.util.*;

public class Main {
    static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static int in() throws IOException {
        st.nextToken();
        return (int) st.nval;
    }

    //    static long nextLong() throws IOException {
//        st.nextToken();
//        return Math.round(st.nval);
//    }
//
//    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//
//    static String nextLine() throws IOException {
//        return br.readLine();
//    }
    static class Edge {
        public int to, next;
    }

    static final int MAX = 101, MAXC = 5001;
    static int n, c, count = 0, cnt = 0, time = 0;
    static int[] w = new int[MAX], val = new int[MAX], W = new int[MAX], V = new int[MAX], head = new int[MAX], oldHead = new int[MAX], from = new int[MAX], dfn = new int[MAX], low = new int[MAX], belong = new int[MAX], inDegree = new int[MAX];
    static Edge[] edges = new Edge[MAX], oldEdges = new Edge[MAX];
    static int[][] dp = new int[MAX][MAXC];
    static Deque<Integer> stack = new ArrayDeque<>();
    static boolean[] inStack = new boolean[MAX];

    public static void main(String[] args) throws IOException {
        n = in();
        c = in();
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= c; j++) {
                dp[i][j] = -0x3f3f3f;
            }
        }
        for (int i = 1; i <= n; i++) {
            W[i] = in();
        }
        for (int i = 1; i <= n; i++) {
            V[i] = in();
        }
        for (int u = 1; u <= n; u++) {
            from[u] = in();
            if (from[u] != 0) {
                addToOld(from[u], u);
            }
        }
        for (int i = 1; i <= n; i++) {
            if (dfn[i] == 0) {
                tarjan(i);
            }
        }
        count = 0;
        for (int i = 1; i <= n; i++) {
            if (belong[from[i]] != belong[i]) {
                addTo(belong[from[i]], belong[i]);
                inDegree[belong[i]]++;
            }
        }
        for (int i = 1; i <= cnt; i++) {
            if (inDegree[i] == 0) {
                addTo(0, i);
            }
        }
        dfs(0);
        out.println(dp[0][c]);
        out.close();
    }

    static void tarjan(int u) {
        dfn[u] = low[u] = ++time;
        inStack[u] = true;
        stack.push(u);
        for (int i = oldHead[u]; i != 0; i = oldEdges[i].next) {
            int v = oldEdges[i].to;
            if (dfn[v] == 0) {
                tarjan(v);
                low[u] = Math.min(low[u], low[v]);
            } else if (inStack[v]) {
                low[u] = Math.min(low[u], dfn[v]);
            }
        }
        if (dfn[u] == low[u]) {
            ++cnt;
            int v;
            do {
                v = stack.pop();
                belong[v] = cnt;
                w[cnt] += W[v];
                val[cnt] += V[v];
                inStack[v] = false;
            } while (v != u);
        }
    }

    static void dfs(int u) {
        for (int i = w[u]; i <= c; i++) {
            dp[u][i] = val[u];
        }
        for (int i = head[u]; i != 0; i = edges[i].next) {
            int v = edges[i].to;
            dfs(v);
            for (int j = c - w[u]; j >= 0; j--) {
                for (int k = 0; k <= j; k++) {
                    dp[u][j + w[u]] = Math.max(dp[u][j + w[u]], dp[u][j - k + w[v]] + dp[v][k]);
                }
            }
        }
    }

    static void addTo(int u, int v) {
        edges[++count] = new Edge();
        edges[count].to = v;
        edges[count].next = head[u];
        head[u] = count;
    }

    static void addToOld(int u, int v) {
        oldEdges[++count] = new Edge();
        oldEdges[count].to = v;
        oldEdges[count].next = oldHead[u];
        oldHead[u] = count;
    }
}
2024/3/11 16:29
加载中...