【筆記】tarjian演算法 求強連通分量
求解強連通分量
目的
求解強連通分量,縮環,利用節點的sccno編號重新建圖,達到題目的要求或者將原圖轉為DAG,進行圖上DPor最短路演算法
演算法流程
變數宣告:
dfn:該節點的dfs編號
low:該節點及其後代能夠追溯到的最早的祖先的dfn編號
1.到達新節點,更新dfn,將low初始化為本身的dfn序號,並將其壓入棧中
2.遍歷u的子節點v,
如果dfn[v]=0,即v還沒有被訪問過,那麼< u,v >是一條樹邊,v是u的後代,對v進行tarjian操作,根據low陣列的定義,v能到的的low,u也能到達,所以用low[v]更新low[u]
如果dfn[v]!=0&&sccno[v]!=0,說明v是u的祖先,且v不屬於之前的強連通分量,那麼用dfn[v]更新low[u]
3.如果dfn[u]==low[u]說明u節點是一個強連通分量的第一個節點,那麼將棧內元素彈出,直至彈出元素為u,目的是將不同的scc區分開來。
細節理解
dfn[v]!=0&&sccno[v]!=0,v號節點必須不屬於其他scc的原因
原理不會,但是我有例項啊
如圖,u是下面的節點,v是上面的被指向的節點。顯然v在一個scc中,u自己是一個scc
此時,如果用dfn[v]更新low[u],那麼low[u]!=dfn[u],在之後的出棧操作中,u就不會被當做一個單獨的強連通,這與圖示不符。
模板
void tarjian(int u){
dfn[u]=low[u]=++dfn_cnt;
s[++top]=u;
for(int i=fisrt[u];i!=-1;i=next[i]){
int v=e[i].t;
if(!dfn[v]){
tarjian(v);
low[u]=min(low[u],low[v]);
}
else if(!sccno[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
++scc_cnt;
for(;;){
int x=s[top];
top--;
sccno[x]=scc_cnt;
if(x==u) break;
}
}
return ;
}
粘一發black學長http://blog.csdn.net/loi_black的板子,black學長新開陣列in_stack記錄同一強連通分量,避免了對!sccno[v]的理解,感謝教練教我tarjian
void group(int x)
{
dfn[x]=low[x]=++tot; //累加遍歷序號
stack[++snum]=x; //把這個點壓入棧內
in_stack[x]=1; //表示這個元素在棧記憶體在
for(int i=first[x];i;i=next[i])
{
int u=hh[i].t;
if(!dfn[u]) //這個點沒有搜過,所以這條邊是樹邊
{
group(u);
low[x]=min(low[x],low[u]); //用low值更新low值
}
else if(in_stack[u]) //搜過且在棧內,他們屬於一個強連通分量,這條邊是一條非樹邊
low[x]=min(low[x],dfn[u]); //用dfn更新它的low值
}
if(dfn[x]==low[x]) //x是這個強連通分量中在dfs時最先搜到的點
{
cnt++;
while(true)
{
jlqlt[stack[snum]]=cnt; //棧內的元素都是在一個強連通分量裡面
size[cnt]++; //這個是記錄每個強連通分量的大小
in_stack[stack[snum]]=0; //彈棧
snum--;
if(stack[snum+1]==x) //一直到彈到屬於這個強連通分量中的元素全被彈乾淨
break;
}
}
}
相關文章
- 圖之強連通、強連通圖、強連通分量 Tarjan演算法演算法
- Tarjan演算法求強連通分量總結演算法
- 強連通分量(Tarjan演算法)演算法
- Tarjan 求有向圖的強連通分量
- Tarjan演算法(強連通分量分解)演算法
- 強連通分量
- 圖論——強連通分量(Tarjan演算法)圖論演算法
- 強連通分量-tarjan演算法模板詳解演算法
- 求有向圖的強連通分量(c語言版)C語言
- kosaraju 和 tarjan演算法詳解(強連通分量)演算法
- 演算法學習之路|強連通分量+縮點演算法
- Tarjan演算法三大應用之強連通分量演算法
- 強連通分量及縮點tarjan演算法解析演算法
- 強連通分量及縮點 演算法解析及例題演算法
- 【模板】tarjan 強連通分量縮點
- 尋找圖的強連通分量:tarjan演算法簡單理解演算法
- POJ 2186 Popular Cows(強連通分量縮點,Tarjan演算法)演算法
- 20行程式碼實現,使用Tarjan演算法求解強連通分量行程演算法
- 圖論複習之強連通分量以及縮點—Tarjan演算法圖論演算法
- 強連通圖的演算法演算法
- 強連通分量與縮點(Tarjan演算法)(洛谷P3387)演算法
- Trajan演算法(強連通+縮點)演算法
- HDU2767Proving Equivalences[強連通分量 縮點]UI
- 強連通演算法--Tarjan個人理解+詳解演算法
- 【筆記/模板】無向圖的雙連通分量筆記
- 筆記--連結串列演算法筆記演算法
- 「學習筆記」雙連通分量、割點與橋筆記
- 強化學習演算法筆記之【DDPG演算法】強化學習演算法筆記
- 強化學習筆記之【SAC演算法】強化學習筆記演算法
- 抓間諜(強連通)
- 邊分治維護強連通分量(CF1989F,P5163)
- 強化學習-學習筆記15 | 連續控制強化學習筆記
- 有向圖的連通性(判強連通)
- 強連通------tarjan演算法詳解及與縮點聯合運用演算法
- 連通圖與Tarjan演算法演算法
- 資料結構和演算法學習筆記八:帶權連通圖的最小生成樹資料結構演算法筆記
- 001 通過連結串列學習Rust筆記之前言Rust筆記
- 強化初學筆記筆記