tarjanアルゴリズムより詳細な説明&& && tarjanロスP2002バレーはメッセージの説明を広める一般的なトラブルシューティング

兄のいるのでより長く、より具体的な私よりも書くために、私はサムアップについて書きます

はじめに:

我々はすべて知っているように、図の多くのリングと呼ばれるものがあります。

このアルゴリズムのために多くのものは、頭痛です。(Suchasダイクストラ)

より深い:に属するリングの強いリンクコンポーネント(強連結成分)

定義:Gの2つの頂点の各々に強固に接続がある場合、Gは、強連結グラフです。強連結成分と呼ばれる図接続部分グラフに大きな力があります。

例えば:( 自閉症に熟練絵画

 

中国聯通は、赤い円の中に強力なコンポーネントです。

この事については、行うことがより困難な他のアルゴリズム。

だから我々は近くにこの事を置く、または強いユニコムコンポーネント、または他のいくつかのアクション、コールに属しているすべての要素を見つけるためにtarjan開発tarjanアルゴリズムを。

彼の名前の是正:Tarjanは、読み方を聞きます。

強いリンク・コンポーネントのtarjanアルゴリズムについては、以下のステップ:

1. 2つのアレイDFNおよび低定義

DFNは、[x]はxのノードが複数の横断することが最初に表します。

低[x]はxのDFNおよびそのすべてのサブツリーエッジの最小値を表します。

2は、我々はポイントにトラバース格納するためのスタックを使用し、スタックレコードの著しいポイントに現在の検索が真です。

図3は、現在のノードのそれぞれの子のために、以前にトラバースされていない場合、ダウントラバース、および低分を通過後の値取りする:低[X] =分(低[X]を、低[V]) :あなたはすでにに横断する前に通過した場合、それは[V] = 1、我々は、検索、値DFNの直接転送ダウン続行されませんである低[X-] =分(低[X-]、DFN [Vを])

図4に示すように、低い値に現在のノードとそのすべてのサブツリーエッジの最小DFNを表し、我々は低いと考えることができ、低の値に等しい電流ノードDFNの値場合は、逆流DFNに円形に渡され、また、中国聯通の構成要素の強い代表を見つけ、そして私たちは、スタックのすべての現在のトップを置く中国聯通の強力なコンポーネントの一部としての要素で現在の要素まで、スタックからポップされます。

アルゴリズムのメインフレームは、深い検索の性質を完了しています。

具体的には、ノードは、自身にそれ自体ので、チャイナユニコムの強い成分と考えることができます。

コードの場合:

 

ボイド Tarjan(INT U){ 
    DFN [U] = ++ IND; 
    低[U] = DFN [U]; // DFNが低く、初期化、初期値DFN低電流、低サブノードの更新であってもよいです。
    S [トップ++] = U; // Sの代表者は、強力なリンクコンポーネントを維持するために使用されるスタック。
     [U] = 1 ; // BOOL配列にスタックタグ内
    int型 I =ヘッド[U]; I; I = E [I] .next){ // チェーン前StarRam図
        INT V E = [I] .TO; // 
        IF(DFN [V] == 0){ // になっていない場合 
            Tarjan(V); //はダウン検索を続ける 
            低[U] =分(低 [Uを]、低[V]); //低い値を更新 
        }  { // 扁リールDAO、ZI及びVのBuザイシュウリ・ミアン
            IF [V]){ // ザイリ・ミアン占 
                低い[U] =分(低[U]、DFN [V ]); // 更新が、なぜDFNが低く、以下の詳細
            } 
        } 
    } 
    IF(DFN [U] ==低[U]){ // 強いルートコンポーネントユニコム 
        cnt_scc ++; // マーキングユニコム強い電流成分ID 
        一方(S [トップ] = U!){ // 現在のノードの発射にポップアップし続ける 
            top-- ;
              [S [トップ] = 0 ; 
            SCC [S [トップ] = cnt_scc ;// Tarjan主要な役割は、現在のポイントは最初のいくつかの強力なユニコム成分であるマーク(点を集としても使用することができます)
        } 
    } 
}

 

だから、羅バレーP2002は、この質問はされても非常によくやりました。

アイデア:

明らかに、強力な内部ユニコムの各成分について、限りメッセージを転送すべき点があるように、次いで他の点では、メッセージを転送することができます。

その後、我々はすべての強いユニコムコンポーネントがポイントに縮小するあなたは現在、強いユニコムとその子どもたちが情報を渡すことができたことを確実にするためにコンポーネントを追加する必要がある場合、その後、中国聯通、答えの強力なコンポーネントのすべての統計がゼロです。

コード:

#include <cstdioを> 
する#include <iostreamの>
 使用して 名前空間STD; 

int型N-
 INT M;
 int型FRO;
 INT T;
 INT sccnum = 0 ;
 int型のRu [ 100001 ]; //はユニコム成分の存在または不在のI強度を表し(BOOL )であってもよい
int型 NUM = 0 ;
 int型 ANS = 0 ;
 INT DFN [ 100001 ];
 int型低[ 100001 ];
 int型のヘッド[ 100001 ];
 INTスタック[ 100001 ]。
int型のトップ。
int型 CNT = 0 ;
int型は、 [所属100001 ]。
BOOL   [ 100001 ]。

構造体の縁{
     INT 次へ。
} EDG [ 500002 ]。

インラインint型リード()// 自研快读
{
     INT ANS = 0 チャー CH = GETCHAR()、最後= '  ' ;
    一方、(CH < ' 0 ' || CH> ' 9 ')最後= CH、CH = GETCHAR()。
    一方、(CH> = ' 0 ' && CH <= ' 9 ')ANS =(ANS << 3)+(ANS << 1)+ CH- ' 0 '、CH = GETCHAR()。
    戻る ==最後に' - ' - ?ANS:ANS; 
} 

インラインボイドは(追加INT  からINTに)// 链式存图
{ 
    numは ++ 
    EDG [NUM] .TO = であり; 
    EDG [NUM] .next =ヘッド【から]。
    頭[] = NUM。
} 

ボイド tarjan(INT X)// 主体部分
{ 
    スタック[トップ ++] =のX。
    DFN [X] =低[X] = ++ CNT。
     [X] = 1 以下のためにint型 ; I I = I =ヘッド[X] EDG [I] .next)
    { 
        int型 V = EDG [I] .TO。
        もし(!DFN [V])
        { 
            tarjan(V)。
            低[X] = 分(低[x]は、低[V])。
        } 
        そう であれば [V])
        {
            低[X] = 分(低[X]、DFN [V]); 
        } 
    } 
    IF(DFN [X] == 低[X])
    { 
        sccnum ++ ;
         一方(スタック[トップ] =!X)
        { 
            トップ - ;
              [スタック[トップ] = 0 ; 
            属する[トップ]スタック[] = sccnum; // 強い成分ユニコムとしてマーク
        } 
    } 
} 

int型のmain(){ 
    N- =読む()、M = 読みます() ;
     のためのINT I = 1 ; I <= M; I ++は 
    { 
        FRO =読む()、T = 読む();
         IF(FRO =!T)を追加し(FRO、T); 
    } 
    のためのINT I = 1 ; I <= N - 、Iは++)/ / Tarjan実行する各点について
    、{
         IF(!Tarjan(I)DFN [I]); 
    } 
    のためにINT I = 1 ; I <= N; I ++は
    { 
        ためINT J =頭部[I]; J。 EDG = J [J] .next)// 強いリンクの統計的成分の各点を通る
        {
             int型 V = EDG [J] .TO、
             IF!([I]を属し= [V]属する)のRu = [V]属します]。1 ; 
        } 
    } 
    のためのINT I = 1 ; Iは<= sccnum Iが++)// 度が0である場合、答えは追加する
    {
         IF(!のRu [I])ANS ++を; 
    } 
    のprintf(" %のD "、ANS) ; // エンド
    戻り 0 ; 
}

 記事の主要部分の終わり。

論争のDFNおよび低:低は、分を取り、[V]なぜ低くないと[V] DFNを使うのか?

この問題は、いくつかの時間のためにコミットゴールドDMSのミスに有名な北京大学など、長い時間のためにも議論があると彼はWAのうち、問題を作ったまでは知りませんでした。

私の理解では、このです。

[x]はxの低最小のDFNのサブツリーです:我々は低定義があることに注意してください。 

あなたが訪問している場合、それは現在のノードの祖先でなければなりません。

低い場合には、それはもはや定義を満たしていません。

これは、低域通過DFN語の使用には影響しません。ローパス円バック最終強いルートユニコムコンポーネントに渡されているので、単に低マークエンド伝送路として、他の側に送信低いDFNとその祖先の値に影響を及ぼしません。(非常に感情的な理解)。

低カット点と考えた場合にさらに、その後同化全体ユニコム強い成分を(低い層は、感情的な理解を渡される)入れ、その後、変化の正確にカット点を見つけます。だから、低間違っています。

もちろん、構築するトピックマップデータをより難しくするので、データを持ついくつかの問題は、あなたが低すぎることができ、強力な原因ではありません。また、影響は低収縮単語とポイントのために大きなカット点はありません。

 感情的な理解はあなたの場合は、終了感性が強くない、私は何のアイデアQWQを持っていません。

スパイシー終了。

あなたは、トップバーの言葉を理解するのに役立ちます。

おすすめ

転載: www.cnblogs.com/lbssxz/p/11234738.html