A20880. 完全二叉树
填空题
困难
知识点
题目描述
完全二叉树
题目描述
给定一棵包含n个结点的有根二叉树,结点依次以1,2,...,n编号,根结点编号为1。
对于结点i,其左儿子的编号记为li,右儿子编号记为ri。特别地,如果左儿子不存在则li=0,如果右儿子不存在则ri=0。
树中每个结点都对应一棵以其为根的子树。请你求出给定有根树的所有n棵子树中,有多少棵子树是完全二叉树。
输入格式
第一行,一个正整数n,表示有根二叉树结点数量。
接下来n行,每行两个正整数li,ri,表示结点i的左儿子编号和右儿子编号。
输出格式
输出一行,一个整数,表示所有子树中完全二叉树的数量。
样例
输入样例 1
4
2 3
4 0
0 0
0 0输出样例 1
4输入样例 2
4
2 3
0 0
4 0
0 0输出样例 2
3数据范围
对于40%的测试点,保证1≤n≤500。
对于所有测试点,保证1≤n≤105。
参考答案
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int n;
int l[N], r[N];
int mn[N], mx[N], chk[N];
int ans;
void dfs(int u) {
chk[u] = 1;
if (!u)
return;
dfs(l[u]);
dfs(r[u]);
chk[u] &= chk[l[u]] & chk[r[u]];
mn[u] = 1 + min(mn[l[u]], mn[r[u]]);
mx[u] = 1 + max(mx[l[u]], mx[r[u]]);
chk[u] &= mn[l[u]] >= mx[r[u]];
chk[u] &= mn[u] >= mx[u] - 1;
ans += chk[u];
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &l[i], &r[i]);
dfs(1);
printf("%d\n", ans);
return 0;
}
上一题
下一题