LCA(共通の祖先)の問題

問題の説明

ツリーにおいて、ノードは、ノードX、Zの祖先(即ち、Z深度ノード<ノードx)である場合、Yは、祖先です。そうノードzは、xとyの共通の祖先であることを特徴とします。

その名前は、距離及び最も近い共通の祖先のためのxとyのために、いわゆる共通の祖先を示唆する。

溶液A:アップラベル

あなたは高熱を行い、その結果として、それ以外の交換方法を再生されませんしない限り、

Xはマークされ、すべてのノードを通って上方にルートノードから行ってきました。

Yは、ノードから上がる、最初のノードは、ノードがポイントを求められたときに遭遇した標識されています。

常に最悪の複雑さはO(n)と尋ねます

対処方法2:ツリー乗算方法

ぬるい、プレイああに診察室に非常に適して...

第1の乗算アルゴリズムを理解しています。ダイナミック・プログラミングと同様に

複雑さO((N + M)Nログ)

事前乗算

セットF [X、k]を表し、A 2× K世代祖先。起動していること、2ジャンプxはK個のノードに到達します。あなたはノードにジャンプする場合は、単に存在していない、我々は彼0の値にします。

明らかに、定義により、それを描画することができるF [X、0]はxの親です。

多くのホップのために、得られたK [1、LOGN]の範囲に属するべきです。C ++では、それは次のように記述する必要があります

T =(INT)ログ(N)/ログ(2)+ 1

そして、伝達方程式があります:

F [X、K] = F [F [X、K-1]、K-1]、 2以降K. 1- +2 K. 1 = 2 * 2 、K 1 = 2 K

O(nはLOGN)の時間計算量を要すると予想されます

ボイドBFS(){
    q.push(1 )。
    D [ 1 ] = 1 一方、(q.size()){
         int型のx = q.front(); q.pop()。
        以下のためにINT iがヘッド[X]を=;私は、iは= 次に[I]){
             int型の Y = 終了[I]。
            もし(D [Y])続けます
            D [Y] = D [X] + 1 
            F [Y] [ 0 ] = X。
            INTの J = 1 ; J <= T; J ++ ){
                F [Y] [J] = F [F [Y] [J- 1 ]] [J- 1 ]。
            }
            q.push(Y)。
        }
    }
}

ジャンプ処理のLCA 

上記の前処理から、我々は、アレイのアレイ及びF(乗算)が初期化されているD(深さ)を得ます

私たちは、D [X]> = D [Y](そうでない場合は、あなたが事を入れ替えることができます)と仮定します

1.レッツは、ジャンプアップ言うように高いようにジャンプ、そしてy xは

  どのようにそれを達成するには?列挙。列挙するためのホップ数。2 =列挙ジャンプlogN個の列挙1-2き0なぜまだ注ぎますか?あなたは複雑さを軽減するためにできるだけジャンプしたい回数ので。

  ノードが低くよりyの上にジャンプしようとしているか確認してください。ジャンプが完了している場合、つまり、X = F [X、ジャンプ]みましょう

2.元々Y Xを祖先を示すX == Y(面にYジャンプX)の完了にのみ最初のステップは、存在する場合、LCAはyに等しいです。

3.レッツは、XとYは両方が同じ深さではなく、シンクにを維持するために、一緒にジャンプアップ。まだジャンプを列挙するために、同じ手順に従ってください。限りFとして[X、ジャンプ] Fにオフに割り当てられた[Y、ジャンプ]、等しくありません。

4.鮮鋭化ステップ3の後、x及びyは、Exchangeへの最終ステップで送信されなければなりません。次いで、任意の親ノードは、LCA(x、y)に結合している両方。したがって、この場合のLCA(X、Y)= F [X、0]で

INT LCA(int型のx、int型のY){
     場合(D [X]> D [Y])スワップ(X、Y)
    INT I = T、I> = 0 ; i-- ){
         場合(D [F [Y] [I]]> = D [X])Y = F [Y] [I]。
        もし(x == y)はリターンX。    
    }
    INT ; I> = I T = 0 ; i-- ){
         場合(!F [x]は[I] = F [Y] [i])と、X = F [X] [i]は、Y = F [ Y] [I]。
    }
    リターン F [X] [ 0 ]。
}

 使用

Xからノードの最短経路内のすべてのノードのyの値にツリー要求及び

実際には、これはこのブログを書いての目的であります...

どのようにそれを行うには?実際には、単に自然。すなわち、単一始点最短経路(または直接DFS)を行うために、ルートノードから開始して、です。次いで、距離(X、Y)= Distence(X)+ Distence(Y) - 2 * Distence(LCA)

したがって、のみ最短経路のためのO(N)、及びLCAを求めます。

おすすめ

転載: www.cnblogs.com/Uninstalllingyi/p/11822227.html