Tarjan演算法 強聯通分量

2021-06-23 06:50:17 字數 2246 閱讀 9269

1、基礎知識

在有向圖g,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通(strongly connected)。如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量(strongly connected components)。  下圖中,子圖為乙個強連通分量,因為頂點1,2,3,4兩兩可達。,也分別是兩個強連通分量。

tarjan演算法是基於對圖深度優先搜尋的演算法,每個強連通分量為搜尋樹中的一棵子樹。搜尋時,把當前搜尋樹中未處理的節點加入乙個堆疊,回溯時可以判斷棧頂到棧中的節點是否為乙個強連通分量。棧中節點只有在其所屬的強連通分量已經全部求出時,才會出棧。如果發現某節點u有邊連到搜尋樹中棧裡的節點v,則更新u的low 值為dfn[v](更新為low[v]也可以)。如果乙個節點u已經dfs訪問結束,而且此時其low值等於dfn值,則說明u可達的所有節點,都不能到達任何在u之前被dfs訪問的節點 那麼該節點u就是乙個強連通分量在dfs搜尋樹中的根。此時將棧中所有節點彈出,包括u,就找到了乙個強連通分量。

定義dfn(u)為節點u搜尋的次序編號(時間戳),low(u)為u或u的子樹能夠追溯到的最早的棧中節點的次序號。

low(u)=min

dfn(u)=low(u)時,以u為根的搜尋子樹上所有節點是乙個強連通分量。

2、參考**

/* tarjan演算法:求乙個有向圖g=(v,e)裡極大強連通分量。

強連通分量是指有向圖g裡頂點間能互相到達的子圖。

如果乙個強連通分量已經沒有被其它強通分量完全包含,那這個強連通分量就是極大強連通分量*/

/*low[v]=dfn[v]時,棧裡v以及v以上的頂點全部出棧,乙個極大強連通分量*/

#include#include#define maxl 50

#define min(x,y) ((x) < (y) ? (x) : (y))

//結點定義

typedef struct edge_nodeenode;

typedef structvnode;

typedef vnode vlist[maxl];

typedef structalgraph;

int instack[maxl]; //用於標記是否在棧中

int vis[maxl];

int dfn[maxl],low[maxl];

int depth;

int ind[maxl]=;

int top;

int stack[maxl]; //【【【要用到】】】

int num_scc;

int count_sccele;

int scc[maxl];

algraph *alg=(algraph *)malloc(sizeof(algraph));

//鄰接表生成[有向圖]

void creat_algraph(algraph *alg)

for(k=0;ke;k++) //邊表 }

//鄰接表輸出

void print_algraph(algraph *alg)

printf("\n"); }}

//計算初始化用於dfnlow()和bicon()

void init_tarjan(void)

top=0; //棧初始化

for(int j=0;jn;j++)

stack[j]=-1;

num_scc=0;

}void init_scc(void) //scc塊初始化

void scc_tarjan(int u)

else if(instack[son]) //在棧中

ptr=ptr->next;

} if(dfn[u] == low[u]) //若此,以u為根的強連通分量

while(stack[top] != u);

for(int cn=0;cnvlist[scc[cn]].vertex);

printf("\n"); }}

int main(void)

強聯通分量 tarjan

tarjan演算法思想 dfs節點的時候,用time記錄訪問順序,則父節點會先於子節點訪問。那麼節點u遞迴的過程中找到了父節點 先訪問的 形成乙個環路,這個環路上的所有節點就是乙個強聯通分量。low的作用是用強聯通分量上的最先訪問的節點 訪問到的父節點 得time作為整個強聯通分量所有節點的時間。並...

求強聯通分量 Tarjan演算法

const int maxn 5010 const int maxm 2500000 struct edge edge maxm inthead maxn tot intlow maxn dfn maxn stack maxn belong maxn intindex,top intscc bool...

tarjan求強聯通分量

變數含義說明 pre i i點的被訪問的時鐘編號,被分配後保持不變 low i i點能訪問的最先的點的時鐘編號,隨子節點改變 scc no i i點所在的強聯通分量的編號 dfs clock 時鐘序號,每訪問乙個新的點時都增長1 scc cnt 強聯通分量的編號 棧stk 每訪問乙個節點都壓入棧中他...