Tarjan演算法介紹

2021-08-21 17:04:30 字數 1584 閱讀 1047

tarjan演算法是圖論中的一種演算法,用作於圖的聯通性

(如果沒學過這樣東西的人可以先收藏一下,等學過了在看)

targan演算法的流程

利用dfs來遍歷圖來構建一種數型的結構

tarjan演算法的兩個核心陣列

dfn:我們用dfn陣列記錄

low:我們用low[i]表示乙個節點的子樹中可以到達最小的dfn

(顯然對於乙個剛剛遍歷到的點我們給他賦上乙個新的dfn,low)

給出一張連通的無向圖g,求出至少加入多少條邊才能使得圖g是乙個邊雙連通的。

即求邊雙連通分量把度為一的節點數x (x+1)/2即為答案

注意:求邊雙連通分量時low相同的即為同一組

(標準模板.cpp)

......

const

int m=10005;

bool

map[m][m],vis[m];

int low[m],dfn[m],cnt[m],num,n,m;

void init()

void dfs(int x,int f)else min(low[x],dfn[i]);

}}int main()dfs(1,0);

int ans=0;

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

if(map[i][j])

if(low[i]!=low[j])//注意:求邊雙連通分量時low相同的即為同一組

cnt[low[j]]++;

for(int i=1;i<=n;i++)

if(cnt[i]==1)ans++;

printf("%d",(ans+1)/2);

return

0;}

給出乙個無向圖,你可以在一些點設定一些出口,使得刪去任意乙個點之後,其他所有的點都至少與乙個出口連通,求在出口數量最小情況下的放置出口的方案。

即求點雙連通分量中割點的數量

我們可以用dfs雙連通分量求。因為每個割點一定是雙連通分量中重複部分

(dfs.cpp)

void tarjan(int

x,int f)}}

}void dfs(intx)}

int main()

for(int i=1;i<=n;i++)

}for(int i=1;i<=n;i++)

}printf("%d

%d",ans1,ans2);

}

tip:tarjantarjan縮點

void tarjan(int x,int f=0)}}

}

(30%內容取自處)

ps:本人的第一篇「半原創」,大佬們勿噴,謝謝!

Tarjan演算法介紹

一種由robert tarjan提出的求解有向圖強連通分量的線性時間的演算法。給定無向圖 g v,e 如果割掉點x,圖中的連通塊數量增加,則稱x為g的割點 如果割掉邊e,圖中的連通塊數量增加,則稱e為g的橋或割邊 在圖的深度優先搜尋中,按照每個節點的訪問順序所給每個點編的號,該編號叫做 時間戳 記為...

tarjan演算法原理介紹

證明比較繁瑣,仔細檢查了應該沒有大錯,記錄一下證明過程。在有向圖中,強連通分量的定義是 有向圖的某個子圖,其中任意兩個點之間可以互達。定理1 乙個完整的強連通分量一定包含在一棵深度優先搜尋樹中。定理2 子圖是強連通分量 子圖中的每一條路徑都歸屬於乙個環狀 除非只有乙個點 證明 根據強連通分量的定義,...

tarjan演算法詳解

參考 tarjan演算法在強連通分量分離中運用很廣,書寫簡單,並且可以拓展到圖的割點,割邊上,十分強大 具體思路 令dfn u 表示當前點的時間戳 low u 表示當前點所能到達的點的時間戳中最小的乙個 到達點u時,將其入棧 拓展點u後代 當且僅當dfn u low u 時,棧頂元素全部出棧,此時出...