【递归】对称二叉树
思路
说点题外话,这道题是NOIP2019-pjT4,被称作有史以来最简单的T4,然而...我这个小蒟蒻当时只得了4分(直接输出1),现在回想起来,觉得自己那时是真的智障啊,最可气的是,这道题一读题就可以发现结果很容易为3,哪怕完全不会,直接输出3也明显比直接输出1要好啊——事实证明,直接输出3的得分高的可怕——32分!!!这简直是白给的32分啊!!!自己当时是真的傻,而且这道题真心不难啊,当时自己要是能AC了这道题,现在我就已经是一个参加过省选的淫了......难受啊QAQ
不过,换一个角度看,自己现在感慨曾经的自己多么智障,似乎正是自己进步的体现,而且进步很大!嗯,好吧,我希望我以后也会不断进步,当有一天,我觉得现在的自己也很智障的时候,我就是真正成长起来了!
不扯了,看思路吧:
我们很容易就能想到用递归的方法:
1.枚举根节点,判断其左右两个孩子节点 是否存在 以及 是否相等. 若存在并且点权相等,则一直递归左右两个孩子节点的左右两个孩子节点,重复上述判断。
2.判断好对称二叉树后,就可以计算以该节点为根节点的对称二叉子树的节点数量并取最优值了。
上代码~
Code
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
ll n,flag,v[1000000],l[1000000],r[1000000];
void dc(ll x,ll y)
{
if(x==-1&&y==-1)return;
if(x==-1||y==-1||v[x]!=v[y])
{
flag=0;
return;
}
dc(l[x],r[y]);
dc(r[x],l[y]);
return;
}
ll jc(ll x)
{
ll ans=1;
if(l[x]!=-1)ans+=jc(l[x]);
if(r[x]!=-1)ans+=jc(r[x]);
return ans;
}
int main()
{
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>v[i];
}
for(ll i=1;i<=n;i++)
{
cin>>l[i]>>r[i];
}
ll ans=1;
for(ll i=1;i<=n;i++)
{
if(l[i]!=-1&&r[i]!=-1&&v[l[i]]==v[r[i]])
{
flag=1;
dc(l[i],r[i]);
if(flag==1)
{
ans=max(ans,jc(i));
}
}
}
cout<<ans<<endl;
return 0;
}