1. 程式人生 > >演算法導論(第三版)-複習- 第六部分圖論思考題 22 基本的圖演算法

演算法導論(第三版)-複習- 第六部分圖論思考題 22 基本的圖演算法

22 基本的圖演算法

思考題

22-1 (以廣度優先搜尋來對圖的邊進行分類)深度優先搜尋將圖中的邊分類為樹邊、後向邊、前向邊和橫向邊。廣度優先搜尋也可以用來進行這種分類。具體來說,廣度優先搜尋將從源結點可以到達的邊劃分為同樣的4種類型。
a.證明在對無向圖進行的廣度優先搜尋中,下面的性質成立:
1.不存在後向邊,也不存在前向邊。
2.對於每條樹邊(u, v),我們有v.d = u.d + 1。
3.對於每條橫向邊(u, v),我麼有v.d = u.d 或 v.d = u.d + 1。
b.證明在對有向圖進行廣度優先搜尋時,下面的性質成立:
1.不存在前向邊。
2.對於每條樹邊(u, v),我們有v.d = u.d + 1。
3.對於每條橫向邊(u, v),我們有v.d ≤ u.d + 1。
4.對於每條後向邊(u, v),我們有0 ≤ v.d ≤ u.d。

ANSWER:
a:

  1. 假如(u, v)是前向邊,則搜尋結點v前必搜尋u,則根據BFS,當搜尋結點u以後必先搜尋結點v,則(u, v)是樹邊;同理,若(u, v)是後向邊,則(v, u)是樹邊;矛盾,所以不存在前向邊和後向邊。
  2. 對於每條樹邊(u, v)有v.π = u,切執行v.π = u的同時執行v.d = u.d + 1;在這之後u.d和v.d都不會改變,所以v.d = u.d + 1;得證。
  3. 由(u, v)為橫向邊可知,當搜尋結點u時,v必須在佇列中,否則(u, v)為樹邊,所以v.d ≤ u.d + 1。又由無向圖橫向邊可知v.d ≥ u.d。所以u.d = v.d 或 u.d + 1 = v.d。

b:

  1. 假如(u, v)是前向邊,則u.d < v.d,則搜尋結點u時,結點v仍是白色,則(u, v)必是樹邊,矛盾;所以不存在前向邊。
  2. 同a.2。
  3. 和a.3類似。
  4. 顯然有v.d ≥ 0,又由後向邊可知v.d ≤ u.d,得證。

22-2 (銜接點、橋和雙連通分量)設G=(V,E)為一個連通無向圖。圖G的銜接點是指圖G中的一個結點,刪除該結點將導致圖不連通。圖G的橋是指圖中的一條邊,刪除該條邊,圖就不再連通。圖G的雙連通分量是指一個最大的邊集合,裡面的任意兩條邊都處於同一條簡單環路中。設Gπ=(V,Eπ)為圖G的深度優先樹。
(事實上這裡的雙連通分量是點-雙連通分量,還有邊-雙連通分量)

問題:
a. 證明:Gπ的根結點是圖G的銜接點當且僅當它在Gπ中至少有兩個子結點。
證明:
因為在對無向圖G進行DFS時,每條邊要麼是樹邊,要麼是後向邊,因此當根結點刪除時,如果它有兩個以上的的子結點,這些子結點是無法相互到達的,因此根結點是圖G的銜接點

b. 設結點v為Gπ的一個非根結點。證明:v是G的銜接點當且僅當結點v有一個子結點s,且沒有任何從結點s或任何s的後代結點指向v的真祖先的後向邊。
證明:
考慮v的任意子結點s,如果s及其後代不能連回v的真祖先,那麼顯然,刪除v之後,v的真祖先與s不再連通。
反過來,如果s或它的後代存在一條後向邊連回v的真祖先,則即使刪了v,以s為根的子樹都可以通過這條後向邊與v的真祖先連通。

c. 定義:
v.low=min{u.d
w.d:(u,w)是結點v的某個後代結點u的一條後向邊}
(d為第一時間戳)
請說明如何在O(E)的時間內為所有結點v計算出v.low的值
解:
對圖G進行DFS,設現在遍歷到結點u,初始化u.low=u.d。
接下來尋找拓展結點,設該結點為v.
如果結點v未被訪問過,則我們從結點v處DFS以求得v.low,用其更新u.low
否則如果v不是u的父親,那麼我們用v.d更新u.low

d. 說明如何在O(E)時間內計算出圖G的所有銜接點
解:
c中基本說的差不多了,以下是細節:
進行DFS時同時維護father,確保不把兒子到父親的路徑當成後向邊。
不能邊DFS邊輸出,因為可能多次滿足條件,所以只能做上標記。

e. 證明:圖G的一條邊是橋當且僅當該邊不屬於G中的任何簡單環路。
證明:
若存在一個橋屬於G中的一個簡單環路,那麼刪除這條邊後,該橋的兩端結點根據定義仍然可以通過其他路徑連通,矛盾;而如果一條邊不屬於任何簡單環路,那麼這條邊的兩端節點只能通過這條邊連通(否則會出現新環路),因此刪除這條邊時圖G不再連通,故此時這條邊是橋。

f. 說明如何在O(E)時間內計算出圖G所有橋。
解:
過程其實與求銜接點很相似,但要注意判定過程中有更改:
當u.d>v.low時(u,v)是橋(可以發現等號不能成立)

g. 證明:G的雙連通分量是G的非橋邊的一個劃分
證明:
事實上就是讓你證雙連通分量中刪去任意一個點都不影響連通性。
這是一個雙連通圖顯然的性質,不詳細證了。

h. 給出一個O(E)時間複雜度的演算法來給圖G的每條邊e做出標記。這個標記是一個正整數e.bcc且滿足e.bcc=e’.bcc當且僅當邊e和邊e’在同一個雙連通分量中。
解:
從森林的每個根結點開始DFS,用類似於求銜接點的方法維護每個結點的low值,但為了儲存bcc,我們還要建一個棧來儲存沒有訪問過的邊;如果遍歷的邊為後向邊,我們就用反向邊更新自己(要注意反向邊不能指向父親)

附:邊-雙連通分量可先做一次DFS標記出所有的橋,然後第二次DFS找出邊-雙連通分量,因為邊-雙連通分量是沒有公共結點的,所以第二次DFS保證不經過橋即可。

22-3(歐拉回路)歐拉回路的演算法來自1873年的Hierholzer,前提是假設圖G存在歐拉回路,即有向圖任意點的出度和入度相同。從任意一個起始點v開始遍歷,直到再次到達點v,即尋找一個環,這會保證一定可以到達點v,因為遍歷到任意一個點u,由於其出度和入度相同,故u一定存在一條出邊,所以一定可以到達v。將此環定義為C,如果環C中存在某個點x,其有出邊不在環中,則繼續以此點x開始遍歷尋找環C’,將環C、C’連線起來也是一個大環,如此往復,直到圖G中所有的邊均已經新增到環中。

資料結構如下:
(1) 使用迴圈連結串列CList儲存當前已經發現的環;
(2) 使用一個連結串列L儲存當前環中還有出邊的點;
(3) 使用鄰接表儲存圖G

使用如下的步驟可以確保演算法的複雜度為O(E):
(1) 將圖G中所有點入L,取L的第一個結點
(2) 直接取其鄰接表的第一條邊,如此迴圈往復直到再次到達點v構成環C,此過程中將L中無出邊的點刪除。環C與環CList合併,只要將CList中的點v使用環C代替即可。
(3) 如果連結串列L為空表示歐拉回路過程結束,否則取L的第一個結點,繼續步驟(2)

22-4 (可到達性)設G = (V, E)為一個有向圖,且每個結點u∈V都標有一個唯一的整數值標記L(u),L(u)的取值為集合{1,2,…,|V| }。對於每個結點u∈V,設R(u) = {v∈V:u→v}為從結點u可以到達的所有結點的集合。定義min(u)為R(u)中標記最小的結點,即min(u)為結點v,滿足L(v) = min{L(w):w∈R(u)}。請給出一個時間複雜度為O(V + E)的演算法來計算所有結點u∈V的min(u)。

ANSWER:按照結點L(u)順序對每個結點查詢該結點可到達的結點,並找出最小的L(v),即min(u);
對V個結點進行查詢共計E條邊,所以時間複雜度為O(V + E)。