噢莫加纳加加加 • 1个月前
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node{
int val,l,r;//存孩子节点的权值、左孩子节点的下标、右孩子节点的下标
}tree[N];
int cnt=0,ans=0;//cnt记录节点交换的次数,ans记录最多可以交换节点有几个
bool judge(int root1,int root2)
{
if(root1==-1&&root2==-1)//左右都是-1,空树,返回true
{
return true;
}
if(root1==-1&&root2!=-1||root1!=-1&&root2==-1)//一个是空树,一个不是空树,返回false
{
return false;
}
cnt++;
if(tree[root1].val!=tree[root2].val)//树的节点上的权值不相等,返回false
{
return false;
}
return judge(tree[root1].l,tree[root2].r)&&judge(tree[root1].r,tree[root2].l);//递归往下去求这两个树的子树是不是对称的
}
//求最多可以交换的节点数有多少个
void solve(int root)
{
if(root==-1)
{
return ;//空树,返回
}
cnt=0;//让记录节点交换的次数为0
bool flag=judge(root,root);//调judge函数,看树是不是对称的
if(flag)
{
ans=max(ans,cnt);//看树是不是对称的,不断去更新 最多有多少个节点可以交换
return ;
}
solve(tree[root].l);//往下递归,求左子树
solve(tree[root].r);//往下递归,求右子树
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>tree[i].val;//输入权值
}
for(int i=1;i<=n;i++)
{
cin>>tree[i].l>>tree[i].r;//输入每个节点的左、右孩子节点的下标
}
solve(1);
cout<<ans;
return 0;
}
评论:
请先登录,才能进行评论