树形dp入门

目录

1.树形dp的定义
2.最大独立集
3. 树上背包
4. 树的最小顶点覆盖
5. 树的最长路径

1.树形dp的定义

树形dp是一种dp思想,将dp建立在树状结构的基础上。它是先算子树然后进行合并,即:先遍历子树,遍历完之后把子树的值合并给父亲。
树形dp的关键方法是dfs。从根节点出发,向子节点做深度优先搜索,并由其子节点的最优解合并得到该节点的最优解。

2.最大独立集

2.1 最大独立集的定义
独立集是指图 G 中两两互不相邻的顶点构成的集合。最大独立集是具有最大尺寸的独立集。
2.2例题
没有上司的舞会
题目链接AcWing算法基础课 285.没有上司的舞会 在这里插入图片描述
在这里插入图片描述

2.3思路
本道题是有向图,由上司指向职员。用动态数组去存储图的边。has_fa[i]表示i是否有父节点,1为有,0为没有。
构造两个状态0,1。f[i][0]表示不选择i点时,i点及其子树能得到的最大快乐指数。f[i][1]表示选择i点时,i点及其子树能得到的最大快乐指数。j为i的儿子节点,happy[i]表示i的幸运值。
f[i][0]=∑(max(f[j][0],f[j][1]))
f[i][1]=happy[i]+∑f[j][0]
结果为max(f[root][0],f[root][1])
2.4代码

//AC代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=6010;
int n,happy[N],has_fa[N],f[N][2];
vector<int> e[N];
void dfs(int u)
{
   
    f[u][1]=happy[u];
    for(int i=0;i<e[u].size();i++)
    {
   
        int j=e[u][i];
        dfs(j);
        f[u][1]+=f[j][0];
        f[u][0]+=max(f[j][0],f[j][1]);
    }
}
signed main()
{
   
    cin>>n;
    for(int i=1;i<=n;i++) cin>>happy[i];
    int m=n-1;
    while(m--)
    {
   
        int a,b;
        cin>>a>>b;
        e[b].push_back(a)
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值