• 有向图的强连通分量的求解算法Tarjan


    Tarjan算法

    Tarjan算法是基于dfs算法,每一个强连通分量为搜索树中的一颗子树。搜索时,把当前搜索树中的未处理的结点加入一个栈中,回溯时可以判断栈顶到栈中的结点是不是在同一个强连通分量中。当dfn[u]=low[u]时,以u为根的搜索子树上的所有结点是一个强连通分量,其中dfn[]值表示结点的深度优先数,low[]值表示结点可以到达的优先数最小的祖先。

    Tarjan伪代码如下:

    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).

  • 相关阅读:
    IOI2000 回文字串
    洛谷 P2758 编辑距离
    NOIP2012普及第三题 摆花
    [SCOI2005]骑士精神
    [USACO1.5]八皇后 Checker Challenge
    Codeforces Round #637 (Div. 2) 题解
    核电站---两种DP解法
    POJ1077 八数码问题
    洛谷 P1162 填涂颜色
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/juechen/p/5255885.html
Copyright © 2020-2023  润新知