解题报告——(shuiti)对称二叉树

题目 对称二叉树

题目描述

题目描述

思路

检查是否符合对称条件

条件很简单——结构对称&&点权对称

要做到点权对称其实也就顺便结构对称了

于是条件可以简化为点权对称

可以考虑并行搜索



bool con(int l,int r) {
	if(l == -1&&r == -1)
		return 1;
	if(l == -1||r == -1)
		return 0;
	if(w[l] == w[r])
		if(check(l,r))
			return 1;
	return 0;
}
bool check(int x,int y) {
    if(x == -1&&y == -1)
        return 1;
    if(x == -1||y == -1)
        return 0;
    if(w[x] != w[y])
    	return 0;
	int l = Root[x].l,l1 = Root[y].l;
	int r = Root[y].r,r1 = Root[x].r;
	if(con(l,r)&&con(l1,r1))
		return 1;
	return 0;
}


信仰深搜

就三个点

你就假装右下还有一点id=3


int dfs(int x) {
    if(x == -1) return 0;
	if(check(Root[x].l,Root[x].r)) {
	    int ans = Find(x) + 1;
		return ans;
	}
	int ans = max(dfs(Root[x].l),dfs(Root[x].r));
	return ans;	
}


找答案

加一是加根节点


int Find(int x) {
	int q = 0;
	int l = Root[x].l;
	int r = Root[x].r;
	if(l != -1) q += Find(l) + 1;
	if(r != -1) q += Find(r) + 1;
	return q;
}


另外

读入时要记录这样几个玩意儿


for(i = 1;i <= n;i++)
		scanf("%d",&w[i]);
	for(i = 1;i <= n;i++)
	    scanf("%d%d",&Root[i].l,&Root[i].r);


code


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 1000001
using namespace std;
int w[M];
struct N {
	int l,r;
}Root[M];
bool con(int,int);
bool check(int,int);
//两个函数相互递归调用,并行搜索检查是否符合要求
int dfs(int);
//核心
int Find(int);
//其实就是找有多少个点
int main() {
	int i,n;
	scanf("%d",&n);
	for(i = 1;i <= n;i++)
		scanf("%d",&w[i]);
	for(i = 1;i <= n;i++)
	    scanf("%d%d",&Root[i].l,&Root[i].r);   
	int ans = dfs(1);
	printf("%d",ans);
	return 0;
}

bool con(int l,int r) {
	if(l == -1&&r == -1)
		return 1;
	if(l == -1||r == -1)
		return 0;
	if(w[l] == w[r])
		if(check(l,r))
			return 1;
	return 0;
}
bool check(int x,int y) {
    if(x == -1&&y == -1)
        return 1;
    if(x == -1||y == -1)
        return 0;
    if(w[x] != w[y])
    	return 0;
	int l = Root[x].l,l1 = Root[y].l;
	int r = Root[y].r,r1 = Root[x].r;
	if(con(l,r)&&con(l1,r1))
		return 1;
	return 0;
}
int Find(int x) {
	int q = 0;
	int l = Root[x].l;
	int r = Root[x].r;
	if(l != -1) q += Find(l) + 1;
	if(r != -1) q += Find(r) + 1;
	return q;
}
int dfs(int x) {
    if(x == -1) return 0;
	if(check(Root[x].l,Root[x].r)) {
	    int ans = Find(x) + 1;
		return ans;
	}
	int ans = max(dfs(Root[x].l),dfs(Root[x].r));
	return ans;	
}

总结

信仰很重要

这代码很慢但不至于卡常,还有大量可优化地方,此处不再赘述

但它非常好理解

猜你喜欢

转载自blog.csdn.net/qq_42421714/article/details/84641868