没有题解,我就来写个题解,这个题我们分析来看,一个软件会依赖于另一个软件,那如果出现了环,比如 他们互相依赖,所以这个三个要么不选,要么全选,再思考一下,那就是强连通分量里面的所有点,要么全选,要么全不选。那第一步我们肯定进行强连通分量缩点,雨巨姐姐教育我们,强连通分量缩点后会得到什么!有向无环图,题目中还给定了一个条件一个软件最多依赖另外一个软件,我们很兴奋啊,这不就是一棵树了吗,严谨地说应该是森林,那我们的问题就转化成了在森林上求背包问题,考虑表示的状态为,已经选了这个节点上的物品,此时背包容量为。那么转移方程为的前驱节点。

下面附上一份我的代码,如有错误欢迎各位大佬在评论区或者私信我指出。

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

std::vector<int> e[105], g[105];
int n, m, cnt = 0, num = 0;
int w1[105], v1[105], dfn[105], low[105], col[105], vis[105], w[105], v[105], in[105];
std::stack<int> st;

void tarjan(int u) {
    dfn[u] = low[u] = ++cnt;
    vis[u] = 1;
    st.push(u);

    for (auto v : e[u]) {
        if (!dfn[v]) {
            tarjan(v);
            low[u] = std::min(low[u], low[v]);
        }
        else if (vis[v]) {
            low[u] = std::min(low[u], dfn[v]);
        }
    }

    if (low[u] == dfn[u]) {
        num++;
        while (1) {
            int cur = st.top();
            col[cur] = num;
            vis[cur] = 0;
            w[num] += w1[cur];
            v[num] += v1[cur];
            st.pop();
            if (cur == u) break;
        }
    }
}

int dp[105][505];
void dfs(int u) {
    for (int i = w[u]; i <= m; i++) {
        dp[u][i] = v[u];
    }
    for (auto v : g[u]) {
        dfs(v);
        for (int j = m; j >= w[u]; j--) {
            for (int k = 0; k <= j - w[u]; k ++) {
                dp[u][j] = std::max(dp[u][j], dp[u][j - k] + dp[v][k]);
            }
        }
    }
}

void solve() {
    std::cin >> n >> m;

    for (int i = 1; i <= n; i++) {
        std::cin >> w1[i];
    }
    for (int i = 1; i <= n; i++) {
        std::cin >> v1[i];
    }

    for (int i = 1; i <= n; i++) {
        int p;
        std::cin >> p;
        if (!p) continue;
        e[p].push_back(i);
    }

    for (int i = 1; i <= n; i++) {
        if (!dfn[i]) tarjan(i);
    }
    
    for (int i = 1; i <= n; i++) {
        for (auto v : e[i]) {
            int x = col[i], y = col[v];
            if (x != y) {
                g[x].push_back(y);
                in[y]++;
            }
        }
    }

    for (int i = 1; i <= num; i++) {
        if (!in[i]) {
            g[n + 1].push_back(i);
        }
    }

    dfs(n + 1);
    int ans = 0;
    for (int i = 0; i <= m; i++) {
        ans = std::max(ans, dp[n + 1][i]);
    }
    std::cout << ans << '\n';
}

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);
    std::cin.tie(0);

    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}