求强连通分量Tarjan算法

2021-07-10 18:07

阅读:775

标签:false   信息   int   最小   tarjan   算法   设置   for   lse   

int  dfn[16];       // 时间戳
int  dfn_num = 0;   // 时间 
int  low[16];       // 节点u所能访问到的最小时间戳 

int inSt[16];       // 节点u是否在栈中.

int st[16];
int top = 0; 

// 我们维护的信息.
int col[16];        // 给节点染色, 同一个连通块的节点应该是同一个颜色的.
int col_num = 0;    // 颜色值.
int size[16];       // 每个颜色值所拥有的块数. 

/*
 
第一步:   访问当前节点的所有子节点:   子节点有三种 
    第一种:   未访问过的, 我们对它进行访问, 同时设置它的时间戳dfn[u]和low[u]为++ndfn_num,以及进栈.
    第二种:   访问过的,并且在栈中,我们直接更新我们 当前 节点的low[] --> 注意 应该用low[u] 和 dfn[v]比较. 
    第三种:   访问过的,并且不在栈中的, 我们直接跳过.因为这个时候,所以它已经染色了,属于一个连通块了. 
第二步:   如果dfn[u] == low[u] 说明 已经找到一个连通块了.
          这时候我们要将栈顶元素弹出,直到当前节点. 记得也要修改inSt, 同时维护我们需要的信息. 
*/

void Tarjan(int u) {
    int v, i;
    dfn[u] = low[u] = ++dfn_num; //添加时间戳. 
    st[++top] = u;      // 进栈 
    inSt[u] = true;     // 标示在栈 
    for (i=head[u]; i; i=edge[i].lst) {
        v = edge[i].to;
        if (!dfn[v]) {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (inSt[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if (dfn[u] == low[u]) { 
        col_num++;
        do {
            inSt[st[top]] = false;
             col[st[top]] = col_num;
             size[col_num]++;
        } while (st[top--] != u);
    }
}

 

求强连通分量Tarjan算法

标签:false   信息   int   最小   tarjan   算法   设置   for   lse   

原文地址:https://www.cnblogs.com/cgjh/p/9554594.html


评论


亲,登录后才可以留言!