tarjan複習筆記

2021-09-23 05:54:05 字數 1978 閱讀 8629

tarjan求強連通分量

割點總體思想:遍歷每乙個結點並使用並查集記錄父子關係。

tarjan 是一種dfs的思想。我們需要從根結點去遍歷這棵樹。

當遍歷到某乙個結點(稱之為 x

xx) 時,你有以下幾點需要做的。

將當前結點標記為已經訪問。

遞迴遍歷所有它的子節點(稱之為 y

yy),並在遞迴執行完後用並查集合並 x

xx 和 yyy。

遍歷與當前節點有查詢關係的結點(稱之為 z)(即是需要查詢 lca 的另一些結點),如果 z

zz 已經訪問,那麼 x

xx 與 z

zz 的 lca

lcalc

a 就是 get

fa(z

)getfa(z)

getfa(

z)(這個是並查集中的查詢函式),輸出或者記錄下來就可以了。

這是偽**

void tarjan(int x)

for (i=1;i<=有查詢關係的結點數;i++)edge[500001],ed[500001];

void add(int from,int to)

void tarjan(int now)

else if(!co[to])

}if(low[now]==dfn[now])

--top;

}}int topo()

while(!q.empty())

}int maxn=0;

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

return maxn;

}int main()

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

top=0;

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

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

}cout《可以使用tarjan演算法求割點(注意,還有乙個求連通分量的演算法也叫tarjan演算法,與此演算法類似)。(tarjan,全名robert tarjan,美國計算機科學家。)

首先選定乙個根節點,從該根節點開始遍歷整個圖(使用dfs)。

對於根節點,判斷是不是割點很簡單——計算其子樹數量,如果有2棵即以上的子樹,就是割點。因為如果去掉這個點,這兩棵子樹就不能互相到達。

對於非根節點,判斷是不是割點就有些麻煩了。我們維護兩個陣列dfn和low,dfn[u]表示頂點u第幾個被(首次)訪問,low[u]表示頂點u及其子樹中的點,通過非父子邊(回邊),能夠回溯到的最早的點(dfn最小)的dfn值(但不能通過連線u與其父節點的邊)。對於邊(u, v),如果low[v]>=dfn[u],此時u就是割點。

但這裡也出現乙個問題:怎麼計算low[u]。

假設當前頂點為u,則預設low[u]=dfn[u],即最早只能回溯到自身。

有一條邊(u, v),如果v未訪問過,繼續dfs,dfs完之後,low[u]=min(low[u], low[v]);

如果v訪問過(且u不是v的父親),就不需要繼續dfs了,一定有dfn[v]#include#includeusing namespace std;

int read()

const int n=20005,m=100005;

int head[n],top=0;

struct nodeedge[m<<1];

void add(int u,int v)

int n,m,cnt,dfn[n],low[n],vis[n],tot=0,ans[n],num;

void dfs(int u,int rt)

} else low[u]=min(low[u],dfn[v]); }}

int cmp(int aa,int bb)

} }sort(ans+1,ans+num+1,cmp);

printf("%d\n",num);

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

return 0;

}

tarjan複習小結

雖然是複習,但還是學到許多。過程中遇到四種邊 1 樹枝邊 dfs 搜尋樹上的邊 滿足邊 u,v v 不在棧中 u 為 v 的父節點 2 前向邊 與 dfs 方向一致 祖先指向子孫 沒什麼用 3 後向邊 與 dfs 方向相反 子孫指向祖先 滿足邊 u,v v 在棧中,u 為 v 的祖先節點 4 橫叉邊...

Tarjan 複習小結

一 割點。void tarjan r i,r rt else low i min low i dfn to k if i rt sum 1 ans i 1 注意 在不聯通圖中,應當 for r i 1 i n i if dfn i tarjan i,i 這樣才能保證全部求到,注意根節點.二 橋。vo...

Tarjan專題總結複習

dfn x x 第一次被訪問的時間順序 時間戳 搜尋樹 每個節點只訪問一次,所有訪問過的邊 x,y 構成一棵搜尋樹 low x 定義為以下節點的時間戳的最小值 1.subtree x 中的節點。2.通過 1 條不在搜尋樹上的邊,能夠到達 subtree x 的節點。void tarjan int x...