次小生成樹

2022-05-01 02:00:15 字數 1829 閱讀 7684

別人都寫最小生成樹,我來個次小的,您可別看是小,可是比最小生成樹難了不少。(雖然可能對於

某個強的了不得的大佬

(點選進入翻譯)來說,他應該會很「傲慢」的說:「這不很簡單嗎」)

當時五一我在qbxt上課的時候這個題我想了幾想我才想出來的。

下面我給出**(不會前向星和並查集的去看我的其他部落格)

以下**是在kruskal演算法的基礎上進行修改,加入對x,y兩點在最小生成樹上路徑中最長邊的計算,存入length[ ][ ]陣列。使用鏈式前向星記錄每個集合都有哪些點。為了合併方便,除了head[ ]記錄每條鄰接表的頭節點的位置外,end[ ]記錄每條鄰接表尾節點的位置便於兩條鄰接表合併。mst為最小生成樹的大小,seemst為次小生成樹的大小。在存在權值相同的邊的情況下,seemst有可能等於mst。

並查集部分**略詳見我的另一篇部落格(在此只給出宣告)

1

//並查集部分

2const

int maxn = 1010;3

intufstree[maxn];

4int find(int

x);5

void merge(int x , int y);

並查集下面是kruskal部分

1

//kruskal

2const

int maxe = 100010;3

struct

nodeedge[maxe];89

bool

cmp(node a , node b)

1415

//鏈式前向星的資料結構

16struct

node1;

2021 node1 link[maxn]; //

邊陣列

22int il; //

邊陣列中資料的個數

23int head[maxn]; //

鄰接表的頭節點位置

24int end[maxn]; //

鄰接表的尾節點位置

25int length[maxn][maxn]; //

每兩點在最小生成樹上路徑中最長的邊

26void kruskal(node * edge , int n , int

m) 38 sort(edge + 1 , edge + 1 +m , cmp);

39for(i = 1 ; i <= m ; i ++)

52}

53//

合併兩個鄰接表

54 link[end[y]].next =head[x];

55 end[y] =end[x];

56merge(x , y);

57 k ++;

58 edge[i].select = 1;59

}60}61

} 62

intmain()

70 secmst =inf;

71for(i = 1 ; i <= m ; i ++)

74 }

kruskal

整個演算法執行了一次kruskal 演算法,時間複雜是o(m log m),同時又對整個length[ ][ ] 進行賦值, 時間複雜度為o(n²),最終又進行了時間複雜度為o(m)的遍歷,總的時間複雜度為o(m log m + n²)。

大佬推薦zht大佬

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

次小生成樹

演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...

次小生成樹

分類 圖論 2013 02 12 15 03 32人閱讀收藏 舉報次小生成樹 在求最小生成樹時,用陣列path i j 來表示mst中i到j最大邊權。求完後,直接列舉所有不在mst中的邊,把它加入到mst中構成一棵新的樹,且該樹有環,此環是由剛加入的邊 i,j 造成的,所以可以通過刪除path i ...