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