長い時間がブログを書いていない(あまりにも多くの仕事を非難、私は間違いなく、あまりにもプレイしていないよねえA)
だから、今日は何かに背の高い書き込みがある:強連結します
まず、関連するいくつかの定義が強く//母から学位を接続します
【図強く(強連結グラフ)を意味する接続有向グラフ VIからVJするVJ VIへ、そこから各ペアVI、VJ、VI≠VJ、ため場合、Gを経路 Gが強いと呼ばれています図通信。
大きな強連結と呼ばれる図2の強連結サブグラフ成分(強連結成分)。
もちろん、確かに読まれていない定義を見て、私は栗が説明与えます
私たちは強く接続されているコンポーネント上に3つのまでのフレーム3ヶ所、例えば、これは古典的で特に強いグラフで、次の図を持っています
私たちは、DFS、我々は右から左に横断し、出発から見て、そのパスは1 - > 3 - > 5 - > 6〜図6に示すように、我々は、出ない方法を発見していない5に戻って行き、図6は、それだけでは強連結成分である、任意のポイントに到達することはできません。同様に、図5は、強連結成分です。そして、1 - > 3 - > 4 - > 1 - > 2、私たちはお互いに達することができるので、これは強連結成分です。
Tarjanのアルゴリズム
次に、それは一般的なアルゴリズムに強い通信です。
Tarjanアルゴリズムは、図の深さ優先探索アルゴリズムに基づいている。、探索木の部分木の各強連結成分。検索時に検索ツリーの現在のノード未処理のスタックを追加し、スタックが後戻り場合スタックノードが強くコンポーネントを接続されているかどうかを決定することができます。
定義DFN(u)はuがUまたはUサブツリーのために、低(U)を検索するノード番号(タイムスタンプ)のオーダーであるが、最も早いスタックノードの配列番号に遡ることができます。
場合DFN(U)=低(u)は、uはすべてのサブツリーノードの探索のルートである場合、強連結成分です。
そして、どのようなアルゴリズムを示します。
从1开始DFS,把遍历到的节点加入栈中。搜索到节点u=6时,DFN[6]=LOW[6],找到了一个强连通分量。退栈到u=v为止,{6}为一个强连通分量。
返回到5,发现DFN[5]=LOW[5],退栈后{5}为一个强连通分量。
继续回到1,最后访问2。访问边(2,4),4还在栈中,所以LOW[2]=DFN[4]=5。返回1后,发现DFN[1]=LOW[1],把栈中节点全部取出,组成一个连通分量{1,3,4,2}。
所以,三个强连通分量全部都找出来了。
模板如下:
1 void Tarjan(int u){ 2 dfn[u]=low[u]=++num; 3 st[++top]=u; 4 for (int i=fir[u]; i; i=nex[i]){ 5 int v=to[i]; 6 if (!dfn[v]){ 7 Tarjan(v); 8 low[u]=min(low[u],low[v]); 9 } 10 else if (!co[v]) 11 low[u]=min(low[u],dfn[v]); 12 } 13 if (low[u] == dfn[u]){ 14 co[u]=++col; 15 while (st[top]!=u){ 16 co[st[top]]=col; 17 --top; 18 } 19 --top; 20 } 21 }