树形dp专题练习

本文探讨了如何使用树形动态规划(dp)解决两类树结构问题:一是求解最少删除多少边得到指定大小的子树;二是寻找点权值与边权值非负的子树,最大化叶子结点数量。通过分析洛谷p1272和p1273两道题目,阐述了树形dp的状态转移方程和解题思路。
摘要由CSDN通过智能技术生成

洛谷p1272
题意:给出一棵含有n个结点的树,求最少删除几条边可以得到一个大小为p的子树

题解:树形dp。dp[u][siz]为得到一个以u为根结点大小为siz的树最少需要删除的边数,那么最后结果就是dp[u][p]的最小值+(u是否等于整棵树的根,如果不是则需要+1用于砍掉与根的联系,否则不需要+1)

#include<bits/stdc++.h>

using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
typedef unsigned long long ull;

const int maxn=155;
const int maxn2=2e4+5;
const ll inf=1e15;

int cnt,head[maxn],siz[maxn],dp[maxn][maxn],out[maxn];

struct edge{
   
    int fr;
    int to;
    int nex;
}e[maxn<<1];

void adde(int x,int y){
   
    e[cnt].fr=x;
    e[cnt].to=y;
    e[cnt].nex=head[x];
    head[x]=cnt++;
}

void dfs(int u,int f){
   
    siz[u]=1;
    for(int i=head[u];i!=-1;i=e[i].nex){
   
        int v=e[i].to;
        if(v==f)continue;
        dfs(v,u);
        siz[u]+=siz[v];
    }
    dp[u][siz[u]]=0;
}

void dfs2(int u,int f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值