對稱二叉樹


震驚!!!
耗了我幾次提交的水題為什么是藍色的???
luogu在線IDE為何如此鬼畜???
NOIp普及T4為何如此菜雞???
luogu竟有描述如此少的題解???
(我上次給了辣莫長的題解呀,描述少呀不給過呀)<( ̄ ﹌  ̄)>
luogu管理員自發自審竟通過題解???
(以上全是扯淡並不是人身攻擊yo~,不接受律師函yo~)
好了言歸正傳(突然發現其實沒有數據的輸入法則簡直沒法講,以后把原題傳送門放上):
https://www.luogu.org/problemnew/show/P5018
題面是這樣的:
一棵有點權的有根樹如果滿足以下條件,則被軒軒稱為對稱二叉樹:
1.二叉樹;
2.將這棵樹所有節點的左右子樹交換,新樹和原樹對應位置的結構相同且點權相等.下圖中節點內的數字為權值,節點外的 id 表示節點編號.

現在給出一棵二叉樹,希望你找出它的一棵子樹,該子樹為對稱二叉樹,且節點數最多。請輸出這棵子樹的節點數。
注意:只有樹根的樹也是對稱二叉樹。本題中約定,以節點 T 為子樹根的一棵“子 樹”指的是:節點T 和它的全部后代節點構成的二叉樹。

這就是題面...
之前我看到藍題就溜了...沒想到這么水
這題就是把所有點的情況(子樹大小)跑一邊,然后取合法方案的最大值就完成了...
結合代碼講:

#include<bits/stdc++.h>
using namespace std;
int n;
int c[1000005];
int son[1000005][3];
int size[1000005];
inline void build(const int &now){
	size[now]=1;
	if(son[now][0]!=-1){
		build(son[now][0]);
		size[now]+=size[son[now][0]];
	}
	if(son[now][1]!=-1){
		build(son[now][1]);
		size[now]+=size[son[now][1]];
	}
}
inline bool check(const int &l,const int &r){
	if(l==-1&&r==-1) return 1;
	if(l!=-1&&r!=-1&&check(son[l][0],son[r][1])&&check(son[l][1],son[r][0])&&c[l]==c[r]) return 1;
	return 0;
}
int main(){
	memset(son,-1,sizeof son);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&c[i]);
	for(int i=1;i<=n;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		son[i][0]=a;
		son[i][1]=b;
	}
	build(1);
	int ans;
	for(int i=1;i<=n;i++)
		if(check(son[i][0],son[i][1]))
			ans=max(size[i],ans);
	printf("%d\n",ans);
	return 0;
}

按步驟講:
1.讀入並建樹,
具體方法就是先讀入權值,在將每個節點的子節點整理下,讀入完成...
2.按照樹的深搜方法把以每個節點為根的子樹規格處理下
3.遍歷每個點,求最大的合法最大樹
具體處理子樹方法就是深搜,代碼好理解
判斷是否合法就是將每個條件枚舉判斷一遍,這樣相當於什么都沒說吧
主要是因為這題太水...
然而它還騙了我3次提交的原因就是我ans沒有初始化,全WA,luogu在線IDE有毒!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM