【模板】tarjan

int dfn[maxn]; //第i个点被dfs到次序
int low[maxn];    //二叉搜索树上i所在子数上仍在栈中的最小dfn,low[i]相等的点在一个强连通分量中
bool vis_tarjan[maxn];
stack<int>s_tarjan;
int tot_tarjan;
int cnt_tarjan;
int res_tarjan[maxn];    //储存强连通分量,res[i]表示点i属于第res[i]个强连通分量
int num_tarjan[maxn];    //第i个强连通分量的点数

void tarjan(int x)
{
    dfn[x] = low[x] = ++cnt_tarjan;
    s_tarjan.push(x);
    vis_tarjan[x] = true;
    for (int i = head[x]; ~i; i = e[i].nxt)
    {
        int v = e[i].v;
        if (!dfn[v])
        {
            tarjan(v);
            low[x] = min(low[x], low[v]);
        }
        else if (vis_tarjan[v])
        {
            low[x] = min(low[x], dfn[v]);
        }
    }
    if (low[x] == dfn[x])
    {
        tot_tarjan++;
        while (!s_tarjan.empty() && s_tarjan.top() != x)
        {
            int t = s_tarjan.top();
            res_tarjan[t] = tot_tarjan;
            num_tarjan[tot_tarjan]++;
            vis_tarjan[t] = false;
            s_tarjan.pop();
        };
        s_tarjan.pop();
        res_tarjan[x] = tot_tarjan;
        num_tarjan[tot_tarjan]++;
        vis_tarjan[x] = false;
    }
}

 

posted on 2019-10-20 16:57  thjkhdf12  阅读(153)  评论(0)    收藏  举报