完整

噢莫加纳加加加  •  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;
}

评论:

请先登录,才能进行评论