最小生成樹演算法及例題

2021-10-13 15:31:27 字數 4494 閱讀 9948

什麼是生成樹?對連通圖進行遍歷,過程中經過的點和邊的組合可看成一棵樹,也叫生成樹

kruskal演算法

世界上有著許許多多的鐵路線、公路線,想要從乙個城市到另乙個城市修一條線路需要許多資金,當然,修路的方式有多種多樣,現在我們想知道如何修路能使得這些城市之間形成乙個通訊網,並且使得總耗費最少呢?

如何構建最小生成樹呢?我們需要三個陣列:selected,mindist,parent

洛谷模板題

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

5050

;int edge[maxn]

[maxn]

;int selected[maxn]

;int mindist[maxn]

;int parent[maxn]

;int ans =0;

int tot =1;

void

prim

(int num,

int m)

}for

(int i=

1;iif(selected[k]

)continue

; selected[k]=1

; tot++

; ans +

= edge[parent[k]

][k]

;for

(int j=

1;j<=num;j++)}

}if(tot!=num) cout<<

"orz"

main()

else

if(z[y])

}memset

(parent,-1

,sizeof parent)

;memset

(mindist,

0x3f

,sizeof mindist)

;prim

(n,1);

return0;

}

hdu模板題

這道題坑死我了,一直看了兩個小時沒找到錯誤,一直提示非法訪問記憶體空間,陣列大小也很合適,後來換了c++提交就過了,很奇怪

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

505;

int edge[maxn]

[maxn]

;int selected[maxn]

;int mindist[maxn]

;int parent[maxn]

;int ans =0;

int tot =1;

void

prim

(int num,

int m)

}for

(int i=

1;iif(selected[k]

)break

; selected[k]=1

; tot++

; ans +

= edge[parent[k]

][k]

;for

(int j=

1;j<=num;j++)}

}if(tot!=num) cout<<

"?"

main()

else

if(z[y])

}memset

(parent,-1

,sizeof parent)

;memset

(mindist,

0x3f

,sizeof mindist)

;memset

(selected,0,

sizeof selected)

;prim

(m,1);

}return0;

}

更新一道題

p1265

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

5050

;int selected[maxn]

;double mindist[maxn]

;int parent[maxn]

;double ans =0;

int tot =1;

struct nodest[maxn]

;double

dis(node x, node y)

void

prim

(int num,

int m)

}for

(int i=

1;iif(selected[k]

)continue

; selected[k]=1

; tot++

; ans +

=dis

(st[parent[k]

], st[k]);

for(

int j=

1;j<=num;j++)}

}printf

("%.2lf"

, ans);}

intmain()

相對於prim演算法,kruskal演算法的思想是加邊,可以稱之為加邊法,過程如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

2e5+

100;

struct edgeedge[maxn]

;int set[maxn]

;bool

cmp(edge x,edge y)

intfindset

(int x)

void

kruskal

(int num,

int m)

if(tot == num-

1) cout

"orz"

<}int

main()

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

2e5+

100;

struct edgeedge[maxn]

;int set[maxn]

;bool

cmp(edge x,edge y)

intfindset

(int x)

void

kruskal

(int num,

int m)

if(tot == num-

1) cout

"?"<}int

main()

return0;

}

b站鏈結

Kruskal最小生成樹 演算法模板 例題

已知連通圖g 圖上有n個頂點。生成樹是指圖g的乙個極小 邊最少 連通子圖,生成樹上有n個頂點 n 1條邊,且任意兩點之間都是連通的。最小生成樹 已知帶權連通圖g,圖中有n個頂點,每條邊都有權值。我們要從圖中抽出一棵生成樹,使得樹上所有邊權之和最小,這棵生成樹就叫做 最小生成樹。常見變形應用 1.要求...

最小生成樹演算法及模板

最小生成樹演算法分為 1.prime演算法 o n 2 由點到邊,每次將到集合距離最短的集合外的點加入集合中,在鬆弛集合外的點到集合的距離 2.kruskal 0 mlogm 將邊從小到大排序,迴圈每一條邊,如果兩點未在同一集合裡 並查集維護 則將該邊加入集合中 稠密圖用prime,稀疏圖用krus...

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...