1. 程式人生 > >演算法導論第三版 22.3 深度優先搜尋 課後題答案全解析

演算法導論第三版 22.3 深度優先搜尋 課後題答案全解析

22.3 深度優先搜尋:

1. 問有向圖和無向圖可能存在的三種顏色的點到點之間的邊。

這個問題比較簡單,直接上傳原版答案,但是要注意,有向圖中存在黑色點到其他點的邊,雖然黑色點是已經搜尋結束的,但是這樣的邊始終存在。

有向圖:

 

無向圖:

 

2. 答案如下:

 

注意其中數字沒有重複的,無論如何time值都會+1

3. 給出括號結構,題目中要求的是22-4即下圖:

 

因此括號結構應該為(((())))(()),作者認為參考答案解釋有所不妥。

4. 22.2中證明一位儲存顏色類似。

5. 根據括號化定理可輕鬆證明,略。

6. 證明:在無向圖中,根據深度優先搜尋是先探索(uv)還是先探索(vu)來將邊(uv)分為樹邊或者後向邊,與根據分類列表中的四種類型的次序進行分類是等價的。

證明:首先分類列表中的四種類型,樹邊、前向邊、後向邊、橫向邊,在無向圖中只有樹邊和後向邊。如果uv之間的這條邊,若從uv方向進行搜尋,若先發現的u,則是一條樹邊,然後v也被發現;若先發現的v,則uv的祖先結點,因此這是一條後向邊。和分類一致,得證!

7. Stack來實現深度優先搜尋:

DFS(G){
for each vertex u belong G.V
    u.color = WHITE
    u.pai = NIL
    time = 0;
for each vertex u belong G.V
    if u.color ==WHITE
        DFS_VISIT(G,u)
}
DFS_VISIT(G,u){
    time = time + 1
    u.color = GRAY
    u.d = time
    while stack != empty
        v = stack.pop()
        time = time +1
        v.d = time
        v.color = GRAY
        for each vertex w adjacent to v
            if w.color == WHITE
                stack.push(w)
            time = time +1
            v.f =     time
        time = time +1
        u.f = time 
}

用一個棧來代替迴圈,與網路大部分虛擬碼不同的是,該處加入了time來標記u.du.f。(該部分虛擬碼迴圈和條件的判斷格式與演算法導論書一致)

8. “有向圖G包含一條從結點u到結點v的路徑,並且在深度優先搜尋中u.d<v.d,則結點v是結點u在深度優先森林中的一個後代。”為這句話找出一個反例。

 

如圖左中右三點,從中間點開始深度優先搜尋,先找到左邊的點,再找到右邊的點,深度優先森林中右邊的點不是左邊點的後代,雖然在圖中存在一條從左邊的點到右邊的點的路徑。

9. “如果有向圖G包含一條從結點u到結點v的路徑,則任何對圖G的深度優先搜尋都將導致v.d<=u.f。”為這句話舉出一個反例。

 

仍運用此圖,如果深度優先搜尋從中間點開始,先搜尋右邊點再搜尋左邊點,將會出現右邊點的

f小於左邊點的d

10. 修改深度優先搜尋的虛擬碼,讓其打印出有向圖G的每條邊及其分類。

深度優先森林有樹邊,後向邊,前向邊,橫向邊

(修改為粗體)

DFS(G)

    for each vertex u belong to G.V

        u.color = WHITE

        u.pi = NIL

    time = 0

    for each vertex u belong to G.V

        if u.color == WHITE

            DFS-VISIT (G,u)

DFS-VISIT(G,u)

    time = time + 1

    u.d = time

    u.color = GRAY

    for each v belong to G:Adj[u]

        if v.color == WHITE    

        輸出(u,v)為樹邊

              v.pi = u

              DFS-VISIT(G,v)

        if v.color == GRAY

        輸出(u,v)為後向邊

        if v.color == BLACK  && v.f > u.d

        輸出(u,v)為前向邊

        if v.color == BLACK  && v.f < u.d

        輸出(u,v)為橫向邊

        u.color = BLACK

        time = time + 1

        u.f = time

如修改,在遍歷到一個邊的時候對vcolor屬性和f屬性進行判斷,將不同的邊進行輸出。如果是無向圖,與有向圖相比,無向圖四種邊沒有什麼區別,因此不需要進行調整。

11. 有向圖的一個結點u怎樣才能成為深度優先樹中的唯一結點,即使結點u同時有入邊和出邊.

a) 首先結點u是一個自迴圈且只有自迴圈的結點。

b) 當一個點u出邊指向的點已經被搜尋結束屬於其他深度優先樹,並且接下來搜尋點u,那麼將會出現u是深度優先樹中的唯一結點。

12. 證明略,內容在22.5強連通分支有詳細講解。

修改程式碼標記深度優先樹,算導中DFS演算法中,從圖中找到一個新的結點的時候標記為x,然後在DFS-VISIT中將遍歷到的每個white結點也標記為x。再回到DFS再找到一個新節點的時候標記為x+1,迴圈以上操作。

13. 判斷圖是不是單連通圖。

首先進行拓撲排序。然後為每個結點維護一個連結串列,儲存入度為0的祖先結點。

然後為每個點計算這些表根據拓撲排序從小到大的順序。然後如果我們有一結點,它的兩個以上的前驅結點的連結串列中包含同一個入度為0的祖先結點,我們可以知道,這不是單連通圖了。相反,如果我們發現每個結點的前驅包含不相同的入度為0的結點,我們就可以判斷這個圖是一個單連通圖。