結合例題和**以及注釋可能會更好理解一些:poj 1679 - the unique mst - 次小生成樹
設g = (v,e,w)是連通的無向圖,t是圖g的一顆最小生成樹。
如果有另一棵樹t1,滿足存不存在樹t』,ω(t』)<ω(t1),則稱t1是圖g的次小生成樹。次小生成樹一般又最小生成樹的鄰集求得。
鄰集的概念:
由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n(t)。然後,求t的鄰集中權值和最小的生成樹,即圖g的次小生成樹。
如果只是簡單的列舉,複雜度很高。首先列舉兩條邊的複雜度是o(ve),再判斷該交換是否可行的複雜度是o(v),則總的時間複雜度是o(v2e)。 分析可知,每加入一條不在樹上的邊,總能形成乙個環,只有刪去環上的一條邊,才能保證交換後仍然是生成樹。而刪去邊的權值越大,新得到的生成樹的權值和越小,可以以此將複雜度降為o(ve)。
詳細過程是:在求解最小生成樹的過程中儲存任意兩點之間路徑道中權值最大的那一條,並標記哪些邊在最小生成樹中。求解完之後再掃一遍沒加入生成樹中的邊,在不破壞樹結構的情況下依次進行替換,相當於找出所有可行的鄰集,然後所有鄰集最小的那乙個就是次小生成樹。
網上的更好的方法(暫時沒看懂):首先做一步預處理,求出樹上每兩個結點之間的路徑上的權值最大的邊。然後列舉圖中不在樹上的邊,有了預處理,就可以用o(1)的時間得到形成的環上的權值最大的邊。
次小生成樹(Prim)
這裡的思路就是先用prim演算法求的最小生成樹,然後在prim演算法中新增乙個max陣列,用max陣列存放兩點間的最大距離,並且用乙個use陣列 布林型別 存放是否使用過該邊,最後再在沒有使用的變進行遍歷,找出最小,求的最小生成樹!下面介紹一下利用prim求次小生成樹的主要步驟。1.先求出來最小生成...
次小生成樹 Prim
我們最常見的是最小生成樹,我們最長使用的是prim和kruskal演算法,乙個是對點進行處理,乙個是對邊進行處理,對於次小生成樹來說我們同樣可以使用這兩個方法進行處理,這裡我們先以prim的寫法為例。首先我們要清楚的是什麼是最小生成樹 乙個有 n 個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原...
次小生成樹 prim和kruskal
prim 先用prim求出最小生成樹t,在prim的同時,用乙個矩陣maxd u v 記錄 在t中鏈結任意兩點u,v的唯一的路中權值最大的那條邊的權值,這是很容易做到的,因為prim是每次增加乙個結點s,在此需要儲存節點和其父節點,採用dp,則最大權值要麼是新加入的邊,要麼是父節點到起始點的採用dp...