AcWing 10. 有依赖的背包问题

 #include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m;
int v[N], w[N];
int h[N], e[N], ne[N], idx;
int f[N][N];
//f[i,j]表示所有从以i为根的子树中选,且总体积不超过j的方案  
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u) {
    for(int i=h[u]; ~i; i=ne[i]) {//遍历u号点的所有子树    物品组 
        int son=e[i];
        dfs(e[i]); 
        //分组背包 
        for(int j=m-v[u]; j>=0; j--)//体积 
            for(int k=0; k<=j; k++)//循环决策,选哪个  当前用多少体积 
            //按体积划分 
                f[u][j]=max(f[u][j],f[u][j-k]+f[son][k]);
    }
    //把点u加进去     
    for (int i = m; i >= v[u]; i -- ) f[u][i] = f[u][i - v[u]] + w[u];
    //清空剩余的部分  放不进去的情况 
    for (int i = 0; i < v[u]; i ++ ) f[u][i] = 0;
}

int main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    int root;//找根节点 
    for (int i = 1; i <= n; i ++ ) {
        int p;
        cin >> v[i] >> w[i] >> p;
        if (p == -1) root = i;//说明为根节点 
        else add(p, i);//依赖p号点,那就建一条p指向i的边 
    }
    dfs(root);//从根节点开始递归操作 
    cout << f[root][m] << endl;//表示考虑整课树的情况下,体积不超过m,最大价值是多少 
    return 0;
}

 

 

 

 

posted @ 2019-12-08 01:28  晴屿  阅读(198)  评论(0编辑  收藏  举报