04 P5018 对称二叉树
https://www.luogu.com.cn/problem/P5018
题意
-
对称二叉树包括
- 对称节点的值相等
- 对称结构一致
-
问给出一个二叉树,找到这个二叉树中。最多节点的对称二叉树。
例如:
想法
- 暴力+递归
- 递归思想:
- 出口条件
- 如果到了最后一个节点
- 如果不满足对称结构
- 返回
- 递归返回是否是 对称结构
- 当前状态
- 左右孩子如果满足对称结构
- 那么左孩子的右,和右孩子的左对称吗?
- 出口条件
// P5018 对称二叉树
// Created by majoe on 2020/6/25.
//https://www.luogu.com.cn/problem/P5018
#include <bits/stdc++.h>
using namespace std;
const int N = 10e6+10;
int n,val[N],ch[N][2];
bool flag = true;
int res;
//判断左右节点是否对称
void check(int l ,int r){
if(!flag) return; // 剪枝
if (l == -1 && r == -1) return; //遍历到最底层了,返回
//如果结构不对称,或者值不相等
if (l == -1 || r == -1 || val[l] != val[r]){
flag = false;
return;
}
check(ch[l][0],ch[r][1]);
check(ch[l][1],ch[r][0]);
return;
}
//统计节点x为根的树的节点数
int cnt(int x){
int num = 0;
if(ch[x][0] != -1) num += cnt(ch[x][0]);
if(ch[x][1] != -1) num += cnt(ch[x][1]);
return num + 1;//加上根节点
}
int main(){
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> val[i];
}
for (int i = 1; i <= n; ++i) {
int l,r;
cin >> l >> r;
ch[i][0] = l; ch[i][1]=r;
}
//遍历每个人访问
for (int i = 1; i <= n; ++i) {
flag = true;//先假设是对称的
check( ch[i][0], ch[i][1]);
if(flag){//如果为对称树
res = max(res,cnt(i));
}
}
cout << res;
return 0;
}