对称二叉树

震惊!!!
耗了我几次提交的水题为什么是蓝色的???
luogu在线IDE为何如此鬼畜???
NOIp普及T4为何如此菜鸡???
luogu竟有描述如此少的题解???
(我上次给了辣莫长的题解呀,描述少呀不给过呀)<( ̄ ﹌  ̄)>
luogu管理员自发自审竟通过题解???
(以上全是扯淡并不是人身攻击yo~,不接受律师函yo~)
好了言归正传(突然发现其实没有数据的输入法则简直没法讲,以后把原题传送门放上):
https://www.luogu.org/problemnew/show/P5018
题面是这样的:
一棵有点权的有根树如果满足以下条件,则被轩轩称为对称二叉树:
1.二叉树;
2.将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等.下图中节点内的数字为权值,节点外的 id 表示节点编号.

现在给出一棵二叉树,希望你找出它的一棵子树,该子树为对称二叉树,且节点数最多。请输出这棵子树的节点数。
注意:只有树根的树也是对称二叉树。本题中约定,以节点 T 为子树根的一棵“子 树”指的是:节点T 和它的全部后代节点构成的二叉树。

这就是题面...
之前我看到蓝题就溜了...没想到这么水
这题就是把所有点的情况(子树大小)跑一边,然后取合法方案的最大值就完成了...
结合代码讲:

#include<bits/stdc++.h>
using namespace std;
int n;
int c[1000005];
int son[1000005][3];
int size[1000005];
inline void build(const int &now){
	size[now]=1;
	if(son[now][0]!=-1){
		build(son[now][0]);
		size[now]+=size[son[now][0]];
	}
	if(son[now][1]!=-1){
		build(son[now][1]);
		size[now]+=size[son[now][1]];
	}
}
inline bool check(const int &l,const int &r){
	if(l==-1&&r==-1) return 1;
	if(l!=-1&&r!=-1&&check(son[l][0],son[r][1])&&check(son[l][1],son[r][0])&&c[l]==c[r]) return 1;
	return 0;
}
int main(){
	memset(son,-1,sizeof son);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	for(int i=1;i<=n;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		son[i][0]=a;
		son[i][1]=b;
	}
	build(1);
	int ans;
	for(int i=1;i<=n;i++)
		if(check(son[i][0],son[i][1]))
			ans=max(size[i],ans);
	printf("%d\n",ans);
	return 0;
}

按步骤讲:
1.读入并建树,
具体方法就是先读入权值,在将每个节点的子节点整理下,读入完成...
2.按照树的深搜方法把以每个节点为根的子树规格处理下
3.遍历每个点,求最大的合法最大树
具体处理子树方法就是深搜,代码好理解
判断是否合法就是将每个条件枚举判断一遍,这样相当于什么都没说吧
主要是因为这题太水...
然而它还骗了我3次提交的原因就是我ans没有初始化,全WA,luogu在线IDE有毒!!!

posted @ 2019-07-01 19:31  _Alex_Mercer  阅读(932)  评论(0编辑  收藏  举报