什麼是生成樹?對連通圖進行遍歷,過程中經過的點和邊的組合可看成一棵樹,也叫生成樹
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演算法,第二種演算法稱...