[] NOIP対称バイナリツリー
タイトル説明
以下の条件を玄玄を満たしている場合は、ツリーのルートの少しを持っている権利は、対称バイナリツリーと呼ばれていました:
二分木、
同じ左と交換ノードのすべてこれらの木の右サブツリー、新しいツリーと地点と等しい権利に対応する元のツリー構造。
図中の数字はIDID外側のノードはノード番号を表し、ノードの重みです。
今、私たちは、バイナリツリーを与えられて、私はあなたがそれサブツリー願って、ツリーは対称サブバイナリツリー、およびノードの最大数です。ツリー出力サブツリーノードしてください。
注意:樹木の根のみが対称バイナリツリーです。バイナリツリーノードTとその後続ノードの全て:T「サブツリー」とのサブルートノードにこの問題規則、に。
入力形式
1がルートノードである正の整数nは、ツリーの特定のノードの数、所定のノード数1〜Nの最初の行。
nは正の整数の第2行は、スペース、ノードiのi番目の正の整数の重みVIによって分離しました。次のN 2つの正の整数L_iを、R_iとの線は、各ノードiが左の子の数を表します。左/右の子は、-1手段が存在しない場合。二つの数字の間のスペースで区切られています。
出力フォーマット
総出力ファイルの行は、2つの対称的なフォークツリーノード与えられた最大ツリーを示す整数を含んでいます。
サンプル入力と出力
コピー入力#1
2
1 3
2 -1
-1 -1
出力#1のコピー
1
コピー入力#2
10
2 5 5 4 5 5 2 2 4 3
。9 10
-1 -1
-1 -1
-1 -1
-1 -1
-1 2
3 4
5 6
-1 -1
。7. 8
出力#2をコピーします
3
分析
、サンプルデータの先頭を理解していない人は、混乱少し以上に確認してください。。。。。その後、まだ読み取ることができる大規模な牛を、説明する必要があります。
さらにいくつかの質問より確認する必要があり、サンプルは彼らの最初のシミュレーションであり、それを理解するには良いです。
図1は、第1、データを読み込み、
int v[maxn],l[maxn],r[maxn]; //v权值,l左孩子编号 ,r右孩子编号
我々は最初の子は、対称程度か、子を見しようとしている場合、そのノードは、子について対称であるかどうかを確認するためにノードからトラバース開始し、その後2と
子の周りでなくなるまで、または非対称性。非対称は、その後、ルートとして2番目のノードを入れて、比較を繰り返しました。。。。。。。。
3たびに比較的大きな値、最終的な出力
ローカルコードは疑問を持っていることがあります。
f(l[x],r[y]); //如果该点的左右孩子对称,
f(r[x],l[y]); //看该点的左右孩子的子树是否对称
ノードID 1を持つ子どもについて、対称示すように、それは子供たちの子供の対称についてです場合、参照、
このポイントに注意を払うには、左の子の左の子と右より右の子の右の子、左と右の子のと右の子であります左よりも子供たちの子供たちは、
彼がそれを得たときに、コードを確認してください。
その他のコードは非常に詳述されています。。
コード
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1e7;
int n;
int v[maxn],l[maxn],r[maxn]; //v权值,l左孩子编号 ,r右孩子编号
int ans ; //答案
int is ; //是不是对称
void f(int x,int y){ //检查是否对称
if(x == -1 && y == -1){ //如果没有左右孩子,return
return ;
}
if(x == -1 || y == -1 || v[x] != v[y]){ //如果不是对称
is = 0; //0表示不是对称
return ;
}
f(l[x],r[y]); //如果该点的左右孩子对称,
f(r[x],l[y]); //看该点的左右孩子的子树是否对称
}
int cnt(int x){ //累加节点数
int k=1;
if(l[x] != -1 ){
k += cnt(l[x]);
}
if(r[x] != -1 ){
k += cnt(r[x]);
}
return k;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&v[i]);
}
for(int i=1;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
}
//从最前的节点遍历
for(int i=1;i<=n;i++){
is = 1; //开始先默认是对称
f(l[i],r[i]); //检查是否对称
if(is){ //如果是对称,那就比较取较大值。
ans = max(ans,cnt(i));
}
}
cout<<ans<<endl;
return 0;
}