タイトル説明
深さ、幅およびノードの距離、以下に示す二分木の間。
深さ:4幅:4(ノードの数に同じレベルまで)
ノード間の距離:⑧→⑥、8(3×2 + 2 = 8)
3の⑥→⑦(1×2 + 1 = 3)
注:ノードとの間の距離の定義:方向(アップリンク)のルート2のエッジの数×ノードを、
場合方向(下り方向)へのルートからリーフノードとエッジの数。
入出力フォーマット
入力フォーマット:
第一行動ファイル入力整数N(1≤n≤100)、バイナリツリーノードの数を表します。、xは、(ルート規則が1である)Yがノードからノードへ二つの整数、U、Vの最後の行を次の行のn-1を表し、uがノードvにノードからシーク距離を表します。
出力フォーマット:
3つの数字は、1ラインを順次表す各数は、UがVのノードにノード間の深さ、幅及び間隔の所定のバイナリツリーを表します。
サンプル入力と出力
問題の解決:LCA訓練を受け、訓練を受け、訓練を受け、
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 int型のn; 構造体の縁{ INT に、次の、ヴァル。 } G [ 100010 ]。 int型のTOT; int型 MAXN = 0 ; INTの深さ[ 100010 ]。 int型 ST [ 100010 ] [ 25 ]。 int型の DIST [ 100010 ]。 BOOL使用[ 100010 ]。 int型のヘッド[ 100010 ]。 インライン無効 addedgeは(int型、int型をB) { G [TOT] .TO = B。 G [TOT] .next = ヘッド[A]。 G [TOT] .val = 1 。 ヘッド[A] = TOT ++ 。 } ボイドクリア() { memsetの(使用、偽、はsizeof (使用されます))。 memsetの(頭、 - 1、はsizeof (ヘッド))。 memsetの(深さ、0、はsizeof (深さ))。 } インラインボイドツリー(int型の) { 使用[S] = 1; 以下のために(int型 ;〜I I = I =ヘッド[S] G [i]が.next) { int型 TT = G [i]が.TO。 もし([TT]を使用する) 続けます。 DIST [TT] = DIST [S] + G [i]は.val。 深さ[TT] =深さ[S] + 1 。 MAXN = MAX(深さ[TT]、MAXN)。 ST [TT] [ 0 ] =のS。 用(INTの J = 1 ; J <= 20 ; J ++ ) ST [TT] [J] = ST [ST [TT] [J- 1 ]] [J- 1 ]。 ツリー(TT)。 } } int型 LCA(INT A、INT B) { 場合(深さ[A]> 深さ[B]) スワップ(B) INT D =深さ[B] - 深さ[A]。 以下のために(int型 I = 0、(1 << i)は<= D、iは++ ) { 場合((1 << I)&D) B = ST [B] [I]。 } もし(==のB) を返します。 以下のために(int型 iは= 20、I> = 0 ; i-- ) { もし![I] =(ST [A] ST [B] [I]) { = [I] ST [A]。 B = ST [B] [I]。 } } 戻り STを[A] [ 0 ]。 } int型のP、Q。 INT メイン() { クリア(); scanf関数(" %のD "、&N) 以下のために(int型 i = 1 ; iがn <; iは、++は) { int型、B。 scanf関数(" %D%dの"、&、&B)。 addedge(B) addedge(B、A)。 } のscanf(" %D%dの"、&P&Q)。 深さ[ 1 ] = 1 。 DIST [ 1 ] = 0 ; ツリー(1 )。 printf(" %d個の\ n " 、MAXN)。 int型ワイド= 0 ; 以下のために(int型 I = 1 ; I <= MAXN; iは++ ) { int型 ANS = 0。 int型、T = I; 用(INT J = 1 ; J <= nであり、j ++ ) { 場合(深さ[J] == T) ANS ++ 。 } ワイド = MAX(ANS、幅広); } // のprintf( "%D%D \ n"は、DIST [P]、DIST [Q])。 // のprintf( "%D%D%D"、DIST [P]、DIST [Q]、DIST [LCA(P、Q)])。 printf(" %d個の\ n%D "、ワイド、2 *(DIST [P] -dist [LCA(P、Q)])+ DIST [Q] - DIST [LCA(P、Q)])。 }