Tarjan,我相信大多數人是這么寫的:
void tarjan(int x) { dfn[x]=low[x]=++cnt; st.push(x),vis[x]=1; for(int i=head[x];i;i=nxt[i]) { int u=to[i]; if(!dfn[u]) { tarjan(u); low[x]=min(low[x],low[u]); }else if(vis[u]) low[x]=min(low[x],dfn[u]); } //...... }
那么,在else句中,為什么是low[x]=min(low[x],dfn[u])而非low[x]=min(low[x],low[u])呢?
我們來觀察這樣一個圖:
(畫圖工具畫的有點難看)
很明顯,③是割點。如果從1開始Tarjan,我們發現,如果用dfn更新,那么1、2、3在同一個強連通分量,即low=1。而4、5的low則是3.這樣是正確的。
但如果用low更新的話,4、5的low全部都將更新為1.因為當5查詢到3時,若用low更新5的low,5的low就被更新為3的low——1.這顯然是錯誤的。