树形dp复习 树上依赖背包问题

选课

今天又看了一下这道题,竟然AC不了了

自己的学习效率有点低下

要明白本质,搞透彻

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std;

const int MAXN = 300 + 10;
struct Edge{ int to, next; };
Edge e[MAXN << 1];
int head[MAXN], a[MAXN];
int f[MAXN][MAXN], tot, n, m;

void AddEdge(int from, int to)
{
    e[tot] = Edge{to, head[from]};
    head[from] = tot++;
}

void dfs(int u)
{
    for(int i = head[u]; ~i; i = e[i].next)
    {
        int v = e[i].to; dfs(v);
        for(int t = m; t >= 1; t--)
            _for(j, 0, t - 1) //注意子树最多选t-1个点 
                f[u][t] = max(f[u][t], f[u][t-j] + f[v][j]);
    }
}

int main()
{
    memset(head, -1, sizeof(head)); tot = 0;
    scanf("%d%d", &n, &m); m++; //这是个技巧,加上选0节点 
    _for(i, 1, n)
    {
        int x; scanf("%d%d", &x, &f[i][1]); //注意这里要初始化 
        AddEdge(x, i);
    }
    
    dfs(0);
    printf("%d\n", f[0][m]);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sugewud/p/9831312.html
今日推荐