tarjan複習小結

雖然是複習,但還是學到許多。

tarjan求強連通分量

基礎知識

過程中遇到四種邊
1>樹枝邊:\(dfs\)搜索樹上的邊 滿足邊\((u,v) ,v\)不在棧中 \(u\)\(v\)的父節點
2>前向邊:與\(dfs\)方向一致 祖先指向子孫 沒什麼用
3>後向邊:與\(dfs\)方向相反 子孫指向祖先 滿足邊\((u,v)\). \(v\)在棧中,\(u\)\(v\)的祖先節點
4>橫叉邊:從某個結點指向搜索樹中另一子樹中某結點的邊 滿足邊\((u,v)\), \(v\)在棧中 \(u\)不爲\(v\)的祖先節點

定義兩個數組\(dfn\)\(low\)\(dfn[x]\)表示\(x\)節點是第幾個被遍歷到的。\(low[x]\)表示\(x x\)以及它的所有子樹的出邊的\(dfn\)的最小值,由定義可以得出:

如果\((u,v)\)是樹枝邊 \(low[u]=min(low[u],low[v])\)
如果是橫叉邊或後向邊 \(low[u]=min(dfn[v],low[u])\)

當結點\(u\)的搜索過程結束之後,若\(dfn[u] == low[u]\) 則以\(u\)爲根的搜索子樹上所有還在棧中的結點,是一個強連通分量,可退棧,爲什麼呢????
我也不知道

通俗的說,若\(u\)爲強連通分量的根,那麼它的子孫中的最高祖先應該是它本身。

算法流程

數組的初始化,當首次到達\(u\)這個點時,更新\(low\)\(dfn\)的值, 將\(u\)入棧
更新\(low[u]\)
如果\((u,v)\)是樹枝邊 \(low[u]=min(low[u],low[v])\)
如果是橫叉邊或後向邊 \(low[u]=min(dfn[v],low[u])\)

如果u的子樹全被遍歷完,\(low[u] == dfn[u]\)那麼退棧,退到\(u\)退出,這些退出的元素就是一個強連通分量。

因爲圖有可能有好幾個部分,也就是說,\(tarjan\)圖不連通。那麼我們還要繼續搜索,直到所有點都被遍歷

code

void tarjan(int x) {
    low[x] = dfn[x] = ++cnt, sta[++top] = x, vis[x] = 1;
    for (int i = head[x]; i; i = edge[i].next) {
        int to = edge[i].to;
        if (!dfn[to]) tarjan(to), low[x] = min(low[x], low[to]);
        else if (vis[to]) low[x] = min(dfn[to], low[x]);
    }
    if (dfn[x] == low[x]) {
        num++;
        while (x != sta[top + 1]) {
            vis[sta[top]] = 0;
            top--;
        }
    }
}

for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i); 

模型建立

其實就是縮點,要不然也沒別的用處。

因爲每一個強連通分量中的點都是相互可達的,我們可以將當前這個強連通分量縮成一個點,這個點的權值由題目來定(通常會有強連通分量中的點權和或者點權的最小值)

我們用到染色的思想,因爲退棧的時候退棧的所有元素都是同一個強連通分量中的,所以我們可以在這個時將所有的點都染成同一種顏色,同時處理縮完點之後點的權值。

code

void tarjan(int x) {
    low[x] = dfn[x] = ++cnt, sta[++top] = x, vis[x] = 1;
    for (int i = head[x]; i; i = edge[i].next) {
        int to = edge[i].to;
        if (!dfn[to]) tarjan(to), low[x] = min(low[x], low[to]);
        else if (vis[to]) low[x] = min(dfn[to], low[x]);
    }
    if (dfn[x] == low[x]) {
        num++;
        while (x != sta[top + 1]) {
            vis[sta[top]] = 0;
            col[sta[top]] = num;
            val[num] += a[sta[top]];
            top--;
        }
    }
}

例題

間諜網絡
穩定婚姻
消息擴散
HXY燒情侶
受歡迎的牛
校園網
最大半連通子圖
網絡協議
消息的傳遞
間諜網絡

tarjan求割點或橋

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章