JZOJ 数形dp练习1(树形dp入门)

来源:JZOJ

树形dp练习1

题目描述

给定一棵 n n n 个点的无权树,问树中每个节点的深度和每个子树的大小? (以1号点为根节且深度为 0 0 0

解题思路

  • 暴力 d f s dfs dfs,在 d f s dfs dfs 中如果找到一个 y y y x x x 的子节点, d e e p [ y ] deep[y] deep[y] (深度)就等于 d e e p [ x ] + 1 deep[x]+1 deep[x]+1,然后递归 d f s ( y ) dfs(y) dfs(y),得到 y y y 子树的大小后 c o t [ x ] + = c o t [ y ] cot[x]+=cot[y] cot[x]+=cot[y](因为 y y y x x x 的子节点,所以要把 y y y 的大小加到 x x x 中);

代码君

#include 
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)