树形dp解题框架

文章讲述了如何使用结构体定义和初始化多叉树,并介绍了在编程竞赛中常见的两种问题:使用左孩子右孩子方法求二叉树的最大高度,以及寻找具有最大加权和的子树。重点介绍了DFS算法的应用和注意事项。
摘要由CSDN通过智能技术生成

 一、结构体定义及初始化方法

struct edge
{
	int to,next;
    //to: 第i条边(x,y)的指向y
    //next: 与x连接的上一条边
};

edge e[100004];
int cnt=1;
int head[100004];


void add(int x,int y)
{
	e[cnt].to=y;
	e[cnt].next=head[x];
	head[x]=cnt;//更新与x相连的边为cnt
	cnt++;
}

二、常见考法(洛谷)

1. 左孩子右孩子

题目要求:给定多叉树T,求T以左孩子右孩子方法变成二叉树的最大高度。

其实就是求根节点的子节点个数+最高的子树高度(递推地来看,这个最高地子树高度其实也是它地子节点个数)

void dfs(int x)//遍历以x为根节点的树
{
	int height=0;
	for(int i=head[x];i;i=e[i].next)//这样可以遍历以x为根节点的下一层的所有子节点。
	{
		int v=e[i].to;
		dfs(v);
		height++;//遍历到一个子节点height++
		dp[x]=max(dp[x],dp[v]);
		//cout<<"当前遍历"<<v<<"结点,height="<<height<<" dp["<<x<<"]="<<dp[x]<<endl;
	}
	dp[x]+=height;//dp[2] = 1
}

 注意:本题有明确父子关系,所以add(x,y)只需要一次

2. 最大子树和 / 生命之树

题目本意都是让在T中找到T’,拥有最大加权和。

void dfs(int x,int fa)//以x为根节点构成S。
{
	for(int i=head[x];i;i=e[i].next)
	{
		int v=e[i].to;
		if(v!=fa)
		{
			dfs(v,x);
			if(dp[v]>0)
			{
				dp[x]+=dp[v];
			}
		}
	}
}

注意:像这样没有明显父子关系的树,add(x,y)需要做双向。

并且dfs格式需要写明x和fa,即建树时缺失的顺序需要在这里阐明。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值