题目:

详见链接:P15801 [GESP202603 六级] 完全二叉树 - 洛谷

题目思路:

本题可以使用树形DP做,

要统计所有子树中完全二叉树的数量,可以采用递归的方法对每个节点进行判断。具体步骤如下:

递归判断子树是否为完全二叉树 对于每个节点,递归判断其左右子树是否为完全二叉树,并记录子树的高度和是否为完全二叉树的信息。通过后序遍历的方式,先处理子节点再处理父节点。

计算子树的高度和完全性 对于当前节点,获取其左右子树的高度和完全性信息。如果左右子树的高度满足完全二叉树的条件(左子树高度等于右子树高度,或左子树高度比右子树高1),并且左右子树都是完全二叉树,则当前子树也是完全二叉树。

统计完全二叉树数量 在递归过程中,每当发现一个子树是完全二叉树时,就将计数器加1。最终遍历所有节点后,计数器中的值即为答案。

本题AC代码:

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define int long long 
struct node{
	int l,r;
};
node a[N];
int dp[N],h[N];
int ans,n;
void dfs(int u,int depth){
	h[u]=depth;
	if(a[u].l>0){
		dfs(a[u].l,depth+1);
		h[u]=max(h[u],h[a[u].l]);
	}
	if(a[u].r>0){
		dfs(a[u].r,depth+1);
		h[u]=max(h[u],h[a[u].r]);
	}
	if(a[u].l==0&&a[u].r==0)dp[u]=2;
	else if(a[u].r==0&&h[a[u].l]==depth+1)dp[u]=1;
	else if(h[a[u].l]==h[a[u].r]){
		if(dp[a[u].l]==2&&dp[a[u].r]==2)dp[u]=2;
		else if(dp[a[u].l]==2&&dp[a[u].r]==1)dp[u]=1;
	}else if(h[a[u].l]==h[a[u].r]+1){
		if((dp[a[u].l]==1||dp[a[u].l]==2)&&dp[a[u].r]==2)dp[u]=1;
	}
	ans+=(dp[u]>0);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].l>>a[i].r;
	}
	dfs(1,0);
	cout<<ans;
	return 0;
}

更多推荐