1. 程式人生 > 實用技巧 >模板 tarjan演算法

模板 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;
        }
    }
}