關於tarjan演算法的空間優化

2022-08-22 10:21:09 字數 1741 閱讀 5642

最近隨著對tarjan演算法理解的加深,我發現用另外一種途徑實現tarjan的方法,且可以省去dfn陣列,大大節省了空間。經過大量測試,已經無誤。以下將分階段闡述進行優化的過程。

第一階段

下面來說一下我做出此優化的思路。設任意兩個節點為u,v。縱觀整個tarjan演算法,我們發現,dfn陣列被呼叫的地方只有兩個:在搜尋中將dfn[u]與low[v]比較大小和在回溯中與low[u]比較是否相等。我在這裡將dfn的職責分別分給low與flag。

(一)在比較大小時將low[v],low[u]直接比較,經過思考我們可以發現,在搜尋中,即在不重複訪問節點時,比較dfn[u]和low[v]與直接比較low[u],low[v]是等效的。而同時將dfn反映是否訪問過某個節點的功能交給flag,訪問過的節點記flag為2。

(二)關於在回溯中與low[u]比較是否相等,從本質上**這一操作,我發現這實際上是一種確認,即確定這個節點的low是否被修改過。由此,我們也可以將這個職責分給flag,記被修改過low的,存在於棧中的節點的flag為-1。到這一步,dfn就沒有存在的必要了。

綜上所述,將flag陣列從bool型改為int型,綜合算下來能省下乙個bool型陣列的空間大小。但仍然省的不多,因此有了第二階段的優化。以下是目前的**:(m為邊數,n為頂點數,anemone為tarjan函式,near是鄰接表,個人習慣,求原諒orz)

(別著急,第二階段將在**後面繼續論述,對這個**不感興趣的大佬們也可以跳過直接看第二階段。)

#include#includeusing namespace std;

struct near

ne[10000010];

int h[10000010],flag[10000010],low[10000010],z[10000010],wh=0,cont=0;

int anemone(int x)

if(flag[ne[no].num]==0)

ne[10000010

];int h[10000010],low[10000010],z[10000010],wh=0,cont=0

;char flag[10000010

];int anemone(int

x)

if(flag[ne[no].num]==1

)

}else

if(flag[ne[no].num]==2||flag[ne[no].num]==0

)

}no=ne[no].nex;

}if(flag[ne[x].num]==2

)

else

}printf("\n

");}

return

low[ne[x].num];

}int

main()

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

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

if(flag[ne[no].num]==1

)

}else

if(flag[ne[no].num]==2||flag[ne[no].num]==0

)

}no=ne[no].nex;

}if(flag[i]==2

)

else

}printf("\n

");}}}

return0;

}

關於LCA的離線演算法 Tarjan

利用並查集優越的時空複雜度,我們可以實現lca問題的o n q 演算法,這裡q表示詢問 的次數。tarjan演算法基於深度優先搜尋的框架,對於新搜尋到的乙個結點,首先建立由這個結點 構成的集合,再對當前結點的每乙個子樹進行搜尋,每搜尋完一棵子樹,則可確定子樹 內的lca詢問都已解決。其他的lca詢問...

關於tarjan演算法的一些整理

要noip了,來補一些演算法。當然馬蜂也都是很久以前的了,不喜勿噴。定義 顯然僅在有向圖中有 乙個極大子圖滿足內部任意一點出發可到其他任一點。可以用來縮點。code 一些地方有注釋。注意僅有這個 是沒fa的。void tarjan int u if low u dfn u top 定義 這個順便是有...

Tarjan演算法的改裝

tarjan演算法是用來解決強連通分量問題的常用演算法,演算法是基於深度優先搜尋的架構,在深度優先搜尋的過程中,迭代地求出各個節點u的標值lowlink u 其中 lowlink u min dfn u dfn w 在這裡,w是從u和u的後代點出發用一條後向弧和橫叉弧所能達到的同乙個強連通分支的節點...