1. 程式人生 > >演算法導論第22章:基本的圖演算法

演算法導論第22章:基本的圖演算法

目錄

圖的表示

特殊的圖

圖的遍歷

題選

圖的表示

1.鄰接矩陣(Adjacency Matrix)

2.鄰接連結串列(Adjacency List)

3.完善鄰接連結串列(Implementing Adjacency List)

4.握手定理:無向圖所有結點的度之和 = 邊數 * 2

特殊的圖

1.樹(Tree)

2.有向無環圖(Directed Acyclic Graph)

3.二分圖(Bipartite Graph)

圖的遍歷

1.深度優先搜尋

2.廣度優先搜尋

拓撲排序(Topological Sort)

輸入:DAG圖

輸出:如果e(u, v),則u在v的前面(結果不唯一)

思路一: O(n² + m)

①找到一個入度為0的點,加入到答案,把它的前向邊全部刪除;

②重複這一過程。

思路二:Θ(n + m)

①預計算所有點的入度

②把入度為0的點加入佇列

③對於每個在佇列中的點的連結串列,減去對應點的入度,若入度為0,加入佇列

④重複,直到佇列空

加入佇列的順序即為拓撲序

思路三:Θ(n + m)

深度優先搜尋,記錄u.f為u結點鄰接連結串列被掃描完之後的時間,按f從大到小排序即為拓撲序

只需證明:若e(u, v)則u在v前面。

e被探索時,v不可能為灰色,因為這意味這環;

若v為白色,v必為u的後代,u肯定後被處理完;

若v為黑色,v.f已經確定,必定小於u.f

強連通分量(Strongly Connected Components)

Kosaraju’s Algorithm:Θ(V+E)

①DFS計算出所有結點的掃描連結串列完成時間f

②按f的逆序搜尋樹,合併組成森林即為SCC

歐拉回路(Eulerian Circuit)

無向圖有歐拉回路:連通,且每個節點的度為偶數

無向圖有尤拉路:連通,且擁有奇數度數的結點個數為0或2

哈密爾頓: Looks similar but very hard (still unsolved)!

題選

1.求s->t的簡單路徑條數:拓撲排序+DP

2.判斷圖是否存在環:DFS過程觀察是否有後向邊,至多V次左右

3.給定有向圖G = (V, E),如果對於所有結點對u, v ∈ V,我們有u→v或v→u,則G是半連通的。請給出一個有效的演算法來判斷圖G是否半連通的。證明演算法的正確性並分析其執行時間。

ANSWER:先執行強連通分量演算法,按照第二次DFS結點搜尋順序給連通分量按升序標號(1~k),並生成分量圖SCC(G)。在分量圖SCC(G)中,由於標號為 i+1 的連通分量不可能指向標號為 i 的連通分量,所以只需要從1~k按順序檢測是否存在(1, 2)、(2, 3) ... (k-1, k)的分量的邊。若存在,則半連通;反之,則不是半連通。演算法時間複雜度為O(V+E)。