Tarjan算法是基於dfs算法,每個強連通份量爲搜索樹中的一顆子樹。搜索時,把當前搜索樹中的未處理的結點加入一個棧中,回溯時能夠判斷棧頂到棧中的結點是否是在同一個強連通份量中。當dfn[u]=low[u]時,以u爲根的搜索子樹上的全部結點是一個強連通份量,其中dfn[]值表示結點的深度優先數,low[]值表示結點能夠到達的優先數最小的祖先。算法
Tarjan僞代碼以下:markdown
Tarjan(u)
{
dfn[u] = low[u] = ++dep //dfn[]和low[]的初值
Stack.push(u) //將u壓入棧中
for each (u,v) in E
{
if(v is not visted) //表示結點沒有被訪問過
{
Tarjan(v)//繼續向下搜索
low[u] = min(low[u],low[v])
}
else if(v in Stack)//若是v還在棧中
{
low[u] = min(low[u],dfn[v])
}
}
if(low[u] == dfn[u])//若是u是強連通的根
{
repeat
v = Stack.pop
print v
until (u == v)
}
}
複雜度分析:若是用鄰接表儲存圖,在Tarjan算法執行的過程當中,每個結點被訪問一次,且只出入棧一次,每條邊也被訪問一次,因此時間複雜度爲O(n+m).ui