強連結成分アルゴリズム-Tarjan

長い時間がブログを書いていない(あまりにも多くの仕事を非難、私は間違いなく、あまりにもプレイしていないよねえ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 }

 

おすすめ

転載: www.cnblogs.com/Alan-Anders/p/11225168.html