次小生成樹的兩種演算法

2022-02-14 01:48:59 字數 1448 閱讀 6204

一、「換邊」演算法

用kruskal求最小生成樹,標記用過的邊。求次小生成樹時,依次列舉用過的邊,將其去除後再求最小生成樹,得出所有情況下的最小的生成樹就是次小的生成樹。可以證明:最小生成樹與次小生成樹之間僅有一條邊不同。

這樣相當於執行m次kruskal演算法。

複雜度o(m^2)

示例**:

int

kruskal_mintree()

if(cnt == n-1

)

}if(flag)

return

tmp;

return -1; //

不存在最小生成樹,返回-1

}int

sec_mintree()

if(cnt == n-1

) }}

if(flag && tmp

mini =tmp;

}if(mini ==mod)

mini = -1

;

return

mini;

}

view code

二、「最長邊」法

演算法流程:先加入(x,y),對於一棵樹,加入(x,y)後一定會形成環,如果刪去環上除(x,y)外最大的一條邊,會得到加入(x,y)時權值最小的一棵樹,如果能快速計算最小生成樹中點x與點y之間路徑中最長邊的長度,即可快速解決。

複雜度o(mlogm+n^2)

示例**:

int

fa[n];

const

int m = 100010

struct

edge

edge[m];

struct

adge

g[n];

//邊陣列

inttot,n,m;

int first[n]; //

鄰接表頭節點位置

int end[n]; //

鄰接表尾節點位置

int mp[n][n]; //

任意兩點在最小生成樹路徑上的最長邊長

int findset(int

x)int

cmp(edge ka,edge kb)

void kruskal(edge *edge)

sort(edge+1,edge+m+1

,cmp);

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

}//合併兩個鄰接鍊錶

g[end[fy]].next =first[fx];

end[fy] =end[fx];

fa[fx] =fy;

k++;

edge[i].chose = 1

; }

}}int

main()

}return0;

}

view code

最小生成樹(兩種演算法)

ifndef min tree h define min tree h include include include include include data struct data struct.h include tool tool disjoint set.h 最小生成樹 假設圖中的頂點有n...

最小生成樹兩種解法

運用了貪心的演算法。是從某個頂點開始不斷新增邊的演算法。int cost max v max v 存邊權 int mincost max v 從集合x出發的邊到每個頂點的最小權值 int book max v int v intprim mincost 0 0 int res 0 while 1 i...

最小生成樹的兩種實現

kruskal演算法的實現 根據最一般的kruskal 演算法的實現原理,本人設計並實現的演算法如下 首先在此演算法中,選邊的過程中,要首先對存在邊按權值按非遞減的順序排列,以順序判斷並加入最小生成樹邊的集合。因此設計資料結構 typedef struct myedge,eptr 在此資料結構中,a...