1. 程式人生 > >次小生成樹算法

次小生成樹算法

方法 新的 得到 最小 連通子圖 blog 連通圖 復雜度 如何

  對於一個無向帶邊權連通圖G(V,E),我們一定能從中提取出最小生成樹,那麽對於次小生成樹該如何獲取?記圖G中有效生成樹集合為Z,而T為G的中的總權重最小的生成樹,那麽G\{T}中總權重最小的樹就是次小生成樹。

  我們不妨先考慮這樣一個問題,記T為圖G中的最小生成樹,由於生成樹由|V|-1條邊唯一決定,因此我們可以認為T代表的是最小生成樹中的邊組成的集合。很容易發現次小生成樹必然包含E\T的某條邊,我們可以枚舉每一條E\T中的邊e,並將e的兩端點合並,在此基礎上運行Kruskal或者Prim算法,找到新的生成樹,並將e加入生成樹,就得到了所有含e的生成樹中的權重最小的生成樹,我們之後稱這種樹為含e最小生成樹

。之後尋找這些樹中權重最小的生成樹即為次小生成樹,這個方法是可行的,但是效率非常感人,時間復雜度二者均為O((|E|-|V|)*|V|log2(|V|))。

  事實上可以在O(|E|log2(|V|))時間復雜度內找到次小生成樹。

  首先我們要找到最小生成樹T。之後我們枚舉E\T中的每一條邊e,將e加入T中,此時T內必定存在一個環,且環包含e(|V|邊連通圖必定帶一個環),為了使T再次成為一株合法的生成樹,我們需要移除環中的某條邊,顯然我們不應該移除e(否則何必要加入呢?),我們要移除的是環中權重最大的邊t,之後T再次成為了一株生成樹T‘。能保證得到的樹T‘是含e最小生成樹,事實上我們在合並了e的兩個端點後得到了新的圖G‘,圖G‘中的最小生成樹必定為T‘\{e},這是由於我們在其上運行Kruskal算法時,所有權重小於t的邊會照舊被選入,而在所有權重小於t的邊處理完成後,原本e所在的環也只缺少一條邊t,由於生成樹中不允許有環,因此t不會被加入,到此孤立的連通子圖之間的聯系與在G上建立最小生成樹無二。因此T‘\{e}是G‘上的最小生成樹。若T‘不是G中含e最小生成樹,則存在含e生成樹F‘,但是F‘\e也是G‘的一個生成樹,這意味著F‘\e的總權重小於T‘\e,這與T‘\e是G‘的最小生成樹相悖,假設不成立,故T‘是G中含e最小生成樹。

  那麽如何在O(|E|log2(|V|))時間復雜度內完成上面所有的操作呢,我們只要對於每條邊e,能夠以log2(|V|)時間復雜度快速計算在最小生成樹中e的兩端點之間路徑上的最大的邊即可。這樣的算法是存在的,可以利用LCT(動態樹)實現。

  尋找最小生成樹的時間復雜度為O(|V|log2(|V|)),而在最小生成樹上建立LCT的建立時間復雜度為O(|V|log2(|V|)),為E\T上所有邊e尋找含e最小生成樹的時間復雜度為O((|E|-|V|)log2(|V|)),因此總的時間復雜度為O(|E|log2(|V|)。

次小生成樹算法