Tarjan算法

能解决的问题:

1.求强连通分量

2.求桥

时间复杂度O(n+m),讲解看这里

相关的问题还有:

1.求图的割点

2.求图的点连通度

3.求图的边连通度

 这几个问题遇到了再补充

G是原图,定义的时候可以这样写:vector<vector<int>> G(10005, vector<int>());,数字表示题目里点的数量。

class Tarjan_Algorithm {
public:
    int n;
    vector<int> dfn, low;
    vector<bool> inStack;
    vector<vector<int>> * G;
    int dep;
    stack<int> pStack;
    vector<vector<int>> Scc;
    vector<int> color;
    vector<pair<int, int>> bridge;
    vector<int> component;

    void init(vector<vector<int>> * G, int size);
    void dfs(int x);
    void runTarjan();
};
void Tarjan_Algorithm::init(vector<vector<int>> * Graph, int size) {
    if(size < 0) return;
    G = Graph, n = size;
    dfn.clear(), low.clear(), inStack.clear(), Scc.clear(), color.clear(), bridge.clear();
    dfn = vector<int>(n + 1, 0);
    low = vector<int>(n + 1, 0);
    inStack = vector<bool>(n + 1, false);
    color = vector<int>(n + 1, 0);
    dep = 0;

    while(!pStack.empty()) pStack.pop();
}
void Tarjan_Algorithm::dfs(int x) {
    if(x > n) return;
    inStack[x] = true;
    dfn[x] = low[x] = ++dep;
    pStack.push(x);
    for(int i = 0; i < (*G)[x].size(); i++) {
        int u = (*G)[x][i];
        if(dfn[u] == 0) {
            dfs(u);
            low[x] = min(low[x], low[u]);
            if(dfn[x] < low[u]) {
                bridge.push_back(make_pair(x, u));
            }
        } else {
            if(inStack[u]) low[x] = min(low[x], dfn[u]);
        }
    }
    if(low[x] == dfn[x]) {
        component.clear();
        while(!pStack.empty()) {
            int u = pStack.top();
            pStack.pop();
            component.push_back(u);
            color[u] = Scc.size();
            inStack[u] = false;

            if(u == x) break;
        }
        Scc.push_back(component);
    }
}
void Tarjan_Algorithm::runTarjan() {
    for(int i = 1; i <= n; i++) {
        if(!dfn[i]) dfs(i);
    }
}
View Code
原文地址:https://www.cnblogs.com/dramstadt/p/7942495.html