題目描述
一棵有點權的有根樹如果滿足以下條件,則被軒軒稱為對稱二叉樹:
- 二叉樹;
- 將這棵樹所有節點的左右子樹交換,新樹和原樹對應位置的結構相同且點權相等。
下圖中節點內的數字為權值,節點外的 id 表示節點編號。
現在給出一棵二叉樹,希望你找出它的一棵子樹,該子樹為對稱二叉樹,且節點數 最多。請輸出這棵子樹的節點數。
注意:只有樹根的樹也是對稱二叉樹。本題中約定,以節點 T 為子樹根的一棵“子 樹”指的是:節點TT和它的全部后代節點構成的二叉樹。
輸入格式
第一行一個正整數 n,表示給定的樹的節點的數目,規定節點編號 1∼n,其中節點 1 是樹根。
第二行 n 個正整數,用一個空格分隔,第 i 個正整數 v_i 代表節點 i 的權值。
接下來 n 行,每行兩個正整數 l_i, r_i,分別表示節點 i 的左右孩子的編號。如果不存在左 / 右孩子,則以 −1 表示。兩個數之間用一個空格隔開。
輸出格式
輸出文件共一行,包含一個整數,表示給定的樹的最大對稱二叉子樹的節點數。
輸入輸出樣例
2 1 3 2 -1 -1 -1
1
10 2 2 5 5 5 5 4 4 2 3 9 10 -1 -1 -1 -1 -1 -1 -1 -1 -1 2 3 4 5 6 -1 -1 7 8
3
說明/提示
【輸入輸出樣例 1 說明】
最大的對稱二叉子樹為以節點 2為樹根的子樹,節點數為 1。
【輸入輸出樣例 2 說明】
最大的對稱二叉子樹為以節點 7 為樹根的子樹,節點數為 3。
【數據規模與約定】
共 25 個測試點。
vi≤1000。
測試點 1∼3,n≤10,保證根結點的左子樹的所有節點都沒有右孩子,根結點的右 子樹的所有節點都沒有左孩子。
測試點 4∼8,n≤10。
測試點 9∼12,n≤10^5,保證輸入是一棵“滿二叉樹” 。
測試點 13∼16,n≤10^5,保證輸入是一棵“完全二叉樹”。
測試點 17∼20,n≤10^5,保證輸入的樹的點權均為 1。
測試點 21∼25,n≤10^6。
本題約定:
層次:節點的層次從根開始定義起,根為第一層,根的孩子為第二層。樹中任一節 點的層次等於其父親節點的層次加 1。
樹的深度:樹中節點的最大層次稱為樹的深度。
滿二叉樹:設二叉樹的深度為 h,且二叉樹有 2h−1 個節點,這就是滿二叉樹。
完全二叉樹:設二叉樹的深度為 h,除第 h 層外,其它各層的結點數都達到最大 個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹。
分析:
這道題真的是這幾年最簡單的PJ T4,但是我在考場上居然不會居然不會居然不會啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!一道非常簡單的DFS,隨便搞搞就能過了。。。真沒什么難度,只要會DFS的都會做吧。。。我真想殺一只去年的自己祭天。。。
CODE:
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 const int M=1000005; 8 int n,ans; 9 struct node{ 10 int val,l,r; 11 }tr[M]; 12 int size[M]; 13 int get(){ 14 int res=0,f=1; 15 char c=getchar(); 16 while (c>'9'||c<'0') { 17 if (c=='-') f=-1; 18 c=getchar(); 19 } 20 while (c<='9'&&c>='0'){ 21 res=(res<<3)+(res<<1)+c-'0'; 22 c=getchar(); 23 } 24 return res*f; 25 } 26 int dfs(int u){ 27 if (tr[u].l!=-1) size[u]+=dfs(tr[u].l); 28 if (tr[u].r!=-1) size[u]+=dfs(tr[u].r); 29 return size[u]; 30 } 31 bool ok(int u,int v){ 32 if (u==-1&&v==-1) return true; 33 if (u!=-1&&v!=-1&&ok(tr[u].l,tr[v].r)&&ok(tr[u].r,tr[v].l)&&tr[u].val==tr[v].val) return true; 34 return false; 35 } 36 int main(){ 37 n=get(); 38 for (int i=1;i<=n;i++) tr[i].val=get(),size[i]=1; 39 for (int i=1;i<=n;i++) tr[i].l=get(),tr[i].r=get(); 40 dfs(1); 41 //for (int i=1;i<=n;i++) cout<<size[i]<<endl; 42 for (int i=1;i<=n;i++) 43 if (ok(tr[i].l,tr[i].r)) ans=max(ans,size[i]); 44 printf ("%d\n",ans); 45 return 0; 46 }