關於最小生成樹和最短路徑的幾個有趣問題

  1. Q:不連通的樹不含最小生成樹,爲什麼?
    A:這很容易證明,如果含有最小生成樹,圖必定是連通的;反之,如果圖是連通的,總可以利用prim算法或kruskal算法或者破圈法得到最小生成樹;如果圖不連通,prim算法和kruskal算法也會固執地給出起點所在連通分支的最小生成樹。

  2. Q:將Dijkstra算法求得的起點到其餘點的路徑及路徑上的點拼成一個新的圖,該圖是不是樹?
    A:是。利用反證法,得到的圖一定是連通圖,假設不是樹,則肯定存在迴路,並且起點在這條迴路上,對於該回路上其餘點來說,就找到了兩條從起點到該點的最短路徑,但是Dijkstra算法至多能找出一條,矛盾。所以假設錯誤,得到的連通圖是樹。

  3. Q:那這個樹是不是最小生成樹?
    A:很有可能不是。拿Dijkstra算法和prim算法進行比較,雖然兩者很相似——都是通過添加頂點來實現的,但是添加頂點的條件不同,Dijkstra算法是找未加入點中距離起點的已知最小距離最小的那個點,而prim算法找的是未加入節點中距離已加入節點的距離最小的那個點,所以,得到的結果很有可能不一樣。

  4. Q:同樣是利用鄰接矩陣求任意兩點間的最短路徑,調用N(頂點個數)次Dijkstra算法和一次Floyd算法時間複雜度是否相同?實際執行效率是否相同?

    A:時間複雜度是一樣的,都是O(N3)O(N^3),但是一次Floyd算法的執行效率更高;原因應該是這樣的:Floyd算法是在原有的鄰接矩陣的基礎上進行了 N 次優化,且每次優化都利用到了前面優化的結果,有效地利用了最新數據;而調用 N 次Dijkstra算法,沒有考慮這 N 次之間的聯繫,所以會有一部分的重複工作,舉個例子,假設已經求得 v1 到 v3 的最短路徑和 v2 到 v1 的最短路徑,現在求 v2 到 v3 的最短路徑,如果已知 v1 是該最短路徑上的點,那麼直接將前面得到的兩個最短路徑拼接起來即可,無需假裝不知道傻傻地求出來;總的來說,Dijkstra算法調用 N 次,每次調用都沒用到前面的調用結果,故有一定的重複操作,而Floyd算法的每次更新都是基於最新的更新結果,所以後者的效率更高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章