来源:JZOJ
树形dp练习1
题目描述
给定一棵 nnn 个点的无权树,问树中每个节点的深度和每个子树的大小? (以1号点为根节且深度为 000 )
解题思路
- 暴力 dfsdfsdfs,在 dfsdfsdfs 中如果找到一个 yyy 为 xxx 的子节点,deep[y]deep[y]deep[y] (深度)就等于 deep[x]+1deep[x]+1deep[x]+1,然后递归 dfs(y)dfs(y)dfs(y),得到 yyy 子树的大小后 cot[x]+=cot[y]cot[x]+=cot[y]cot[x]+=cot[y](因为 yyy 是 xxx 的子节点,所以要把 yyy 的大小加到 xxx 中);
代码君
#include <bits/stdc++.h>
using namespace std;
int linkk[200010],deep[200010],cot[200010];
int n,t=0;
struct node
{
int y,next;
}e[200010];
void insert(int x,int y) //邻接表
{
e[++t].y=y;
e[t].next=linkk[x]; linkk[x]=t;
}
void dfs(int x,int father) //dfs
{
cot[x]=1; //因为x本身为1个点,所以初值为1
// deep[x]=deep[father]+1;
for (int i=linkk[x];i;i=e[i].next) //邻接表查询
{
int y=e[i].y;
if (y!=father) //y不是父亲节点
{
deep[y]=deep[x]+1; //深度+1
dfs(y,x);
cot[x]+=cot[y]; //把y的节点数加入x
}
}
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d",&n);
deep[0]=-1;
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
insert(x,y); //邻接表插入
insert(y,x);
}
dfs(1,0);
for (int i=1;i<=n;i++)
{
printf("#%d deep:%d count:%d\n",i,deep[i],cot[i]);
}
return 0;
}
本文深入解析树形DP的概念及应用,通过一道经典题目详细阐述如何使用深度优先搜索(DFS)来求解树中每个节点的深度及其子树大小。代码实现采用邻接表存储树结构,递归计算深度和子树节点数。

被折叠的 条评论
为什么被折叠?



