[3884]羅区バイナリ木問題

タイトル説明

深さ、幅およびノー​​ドの距離、以下に示す二分木の間。

深さ: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のノードにノード間の深さ、幅及び間隔の所定のバイナリツリーを表します。

 

サンプル入力と出力

入力サンプル#1:  コピー
10                                 
1 2                             
1 3                             
2 4 
2 5 
3 6 
3 7 
5 8 
5 9 
6 10 
8 6
出力サンプル#1:  コピー
4 
4 
8

 

 

問題の解決: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 = 0int型、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)])。
}

 

おすすめ

転載: www.cnblogs.com/wuhu-JJJ/p/11229233.html