SCC模板

vector<int> G[maxn];
int pre[maxn], low[maxn], c[maxn];
int n, m;
stack<int> s;
int dfstime, scc_cnt;

void dfs(int u, int fa){
    pre[u] = low[u] = ++dfstime;
    int len = G[u].size();
    s.push(u);
    for (int i = 0; i < len; i++){
        int v = G[u][i];
        if (pre[v] == -1){
            dfs(v, u);
            low[u] = min(low[u], low[v]);
        }
        /*else if (low[v] < pre[u] && v != fa){///双连通里面,这里是通过反向边更新的
            low[u] = min(low[u], low[v]);
        }*/
        else if (!c[v]){///下面为什么是pre[v]而不是low[v](两者都可以)
            low[u] = min(low[u], pre[v]);///因为环装最后总会变回来,一样的
        }
    }
    if (low[u] == pre[u]){
        scc_cnt++;
        while (true){
            int x = s.top(); s.pop();
            c[x] = scc_cnt;
            if (x == u) break;
        }
    }
    return ;
}

 

posted @ 2016-09-23 13:36  知る奇迹に  阅读(277)  评论(0编辑  收藏  举报