Scc 強連通分量 的非遞迴式寫法

2021-08-20 07:21:18 字數 1291 閱讀 7437

強連通分量的遞迴寫法不解釋,如有問題請右轉傳送門:

強連通分量–tarjan個人理解+詳解

優勢:防止tarjan求強連通分量時爆棧

從遞迴式出發,程式是從原來的遞迴程式執行一半,遞迴執行下一層。直至下一層的遞迴呼叫完畢後,再回溯至源程式。而手工棧需要模擬系統棧的呼叫方式,先定義乙個類似於棧的陣列或資料結構,再通過while迴圈呼叫進行模擬運算。

但漏洞是很明顯的,在系統棧的呼叫中,原遞迴程式的執行都只執行到一半,待所有更低階的呼叫結束後再完成下半部分。很明顯,用while迴圈完成的手工棧無法使每一層的運算都恰好停留在向下呼叫時的位置。這時候我們需要根據原來的遞迴程式進行形式上的改寫,尤其是for迴圈部分,需要將迴圈完整的部分進行拆分

具體解釋附在每行**旁,未被注釋部分是非遞迴式寫法,注釋部分是原遞迴寫法:

struct

stack

sp[maxn];

//非遞迴的棧

void tarjan(int u)

if(cur.down)//用所有tarjan過的子孩子更新自己的low值

low[u]=min(low[u],low[cur.down]);

if(cur.ch==-1)

}tp--;

continue;//返回至上一層的tarjan

}v=edge[cur.ch].v;//遍歷u結點的孩子

cur.ch=edge[cur.ch].nxt;//鍊錶存邊

if(!pre[v])//如果未被遍歷則進行tarjan操作

else

if(!belong[v])//如果被遍歷過且目前不屬於任何強連通分量,則用pre[v]更新low[u]的值

low[u]=min(low[u],pre[v]);

}// low[u]=pre[u]=++dfs_clock;

// s[++top]=u;

// for(int i=head[u];i!=-1;i=edge[i].nxt)

//

// else if(!belong[edge[i].v])

//

// }

// if(low[u]==pre[u])

//

// top--;

// }

// }

}

強連通分量SCC

poj2762 題意 給出n個點,對於每個點,如果任意選擇兩點s,e,都滿足s可以到達e或者e可以到達s,則輸出yes,否則輸出no。用了白書裡的模板 參考解決思路是 首先求出原圖g的強連通分量並且縮點,求出縮點後的圖mat,並且求出縮點後所有頂點的入度in。這時我們思考下,如果原圖g要是半連通的,...

SCC(強連通分量)

1.定義 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 sc strongly connected 有向圖中的極大強連通子圖,成為強連通分量 scc strongly connected components 下圖中,子圖為乙個強連通分量,因為頂點1,2,3,4兩兩可達,也分別是兩...

強連通分量(SCC)模版

如題,模版如下 scc cnt為scc計數器,sccno i 為i所在的scc編號 scc cnt為scc個數,scc的 編號從1開始 vector g maxn 圖存在g maxn 中,若有一條從v u的邊,則儲存時先v u 再g v push back u 即結點從0開始編號 int pre m...