模板 tarjan算法

有向图的dfs树
有向图的dfs树包含4种边:
1.树边。每次搜索找到一个还没有被访问过的节点时,生成一条树边
2.返祖边。指向祖先节点的边
3.横叉边。搜索时遇到了一个已经访问过的节点,但是这个节点并不是当前节点的祖先节点
4.前向边。搜索时遇到已经访问过的子树中的节点

图中节点编号为dfs序的编号
绿色代表树边,黄色代表返祖边,红色代表横叉边,蓝色代表前向边

tarjan算法
tarjan算法在有向图的dfs树生成的过程中计算强连通分量
只有反祖边可以形成强连通分量
设立两个数组:
1.dfn数组。存储有向图的dfs序。
2.low数组。存储某个节点可以到达的dfn值最小的祖先节点的dfn值

const int maxn=10010,maxm=100010;
int dfn[maxn],low[maxn],stk[maxn],scc[maxn],top,dfscnt,scccnt;

void tarjan(int u){
    dfn[u]=low[u]=++dfscnt;
    stk[++top]=u;
    for(int v:g[u]){
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!scc[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        ++scccnt;
        while(1){
            int v=stk[top--];
            scc[v]=scccnt;
            if(v==u) break;
        }
    }
}
posted @ 2020-09-04 20:58  fxq1304  阅读(135)  评论(0编辑  收藏  举报