原题传送门ios
说点题外话,这道题是NOIP2019-pjT4,被称做有史以来最简单的T4,然而...我这个小蒟蒻当时只得了4分(直接输出1),如今回想起来,以为本身那时是真的智障啊,最可气的是,这道题一读题就能够发现结果很容易为3,哪怕彻底不会,直接输出3也明显比直接输出1要好啊——事实证实,直接输出3的得分高的可怕——32分!!!这简直是白给的32分啊!!!本身当时是真的傻,并且这道题真心不难啊,当时本身要是能AC了这道题,如今我就已是一个参加过省选的淫了......难受啊QAQspa
不过,换一个角度看,本身如今感慨曾经的本身多么智障,彷佛正是本身进步的体现,并且进步很大!嗯,好吧,我但愿我之后也会不断进步,当有一天,我以为如今的本身也很智障的时候,我就是真正成长起来了!code
不扯了,看思路吧:
咱们很容易就能想到用递归的方法:
1.枚举根节点,判断其左右两个孩子节点 是否存在 以及 是否相等. 若存在而且点权相等,则一直递归左右两个孩子节点的左右两个孩子节点,重复上述判断。
2.判断好对称二叉树后,就能够计算以该节点为根节点的对称二叉子树的节点数量并取最优值了。递归
上代码~ci
#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; }