BZOJ 1149 CTSC2007 风玲Mobiles DFS

25 篇文章 0 订阅

题目大意:给定一棵完全二叉树,可以交换某个节点的左右儿子,求最少交换多少次可以使所有的叶节点深度相差不超过1,且深度较大的叶节点都在深度较小的叶节点左侧

铃抄千

这水题居然还WA了两次- - 脑残害死人啊QAQ

首先DFS一次处理出深度最大和最小的叶节点 如果深度相差>=2则无解

然后再DFS一遍,对于每个节点首先向子节点递归,然后记录左右两棵子树中深度较大叶节点的存在性和深度较小叶节点的存在性

如果两棵子树中都存在深度较大的叶节点和深度较小的叶节点则无解

否则讨论一下是否需要交换 如果需要交换则ans++

最后输出答案就行了- -

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
const int a[4][4]={
	{0,0,0,0},
	{0,0,0,0},
	{0,1,0,1},
	{0,1,0,0}
};
int n,ans,max_dpt,min_dpt=0x3f3f3f3f;
int ls[M],rs[M];

void DFS(int x,int dpt)
{
	if(x==-1)
	{
		max_dpt=max(max_dpt,dpt);
		min_dpt=min(min_dpt,dpt);
		return ;
	}
	DFS(ls[x],dpt+1);
	DFS(rs[x],dpt+1);
}
int Tree_DP(int x,int dpt)
{
	if(x==-1)
		return dpt==min_dpt?2:1;
	int l=Tree_DP(ls[x],dpt+1);
	int r=Tree_DP(rs[x],dpt+1);
	if(l==3&&r==3)
	{
		cout<<-1<<endl;
		exit(0);
	}
	ans+=a[l][r];
	return l|r;
}
int main()
{
	int i;
	cin>>n;
	for(i=1;i<=n;i++)
		scanf("%d%d",&ls[i],&rs[i]);
	DFS(1,1);
	if(max_dpt-min_dpt>=2)
		return cout<<-1<<endl,0;
	if(max_dpt==min_dpt)
		return cout<<0<<endl,0;
	Tree_DP(1,1);
	cout<<ans<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值