1. 初始化集合s(已加入的点的集合) = {}, dist={无穷大}:含义为到集合s的距离
2. 循环n次(每次在集合外找一个距离最小的点加入集合)
在dist集合外找一个距离最小的点t, 加入集合s
更新dist, 用t作为中转点去更新其他点到集合的距离
总结: 和dijstra算法的区别在于一个是更新到起点的距离, 一个是更新到集合v的距离
1. 将所有边按权重从小到大排序 (o(mlogm))
2. 枚举每条边a,b, 权重为c. (o(m))
if a和b不联通, 将边加入集合中
主要是并查集实现
//g: 邻接矩阵
//return: (最小代价, 是否存在最小代价(true:存在))
func prim(g [][]int) (int, bool) {
n := len(g)
dist := make([]int, n)
for i := 0; i < n; i++ {
dist[i] = 0x3f3f3f3f
}
visit := make([]bool, n)
res := 0
for i := 0; i < n; i++ {
t := -1
for j := 0 ;j < n; j++ {
if !visit[j] && (t == -1 || dist[j] < dist[t]) {
t = j
}
}
visit[t] = true
if i == 0 {
dist[t] = 0
}
if dist[t] == 0x3f3f3f3f {
return 0, false
}
res += dist[t]
for j := 0; j < n;j++ {
if !visit[j] && dist[j] > g[t][j] {
dist[j] = g[t][j]
}
}
}
return res, true
}
type Edge struct {
st int
ed int
w int
}
var parent []int
func findpa(a int) int {
if a != parent[a] {
parent[a] = findpa(parent[a])
}
return parent[a]
}
func kruskal(edges []*Edge, n int) (int, bool){
sort.Slice(edges, func(i, j int) bool {
return edges[i].w < edges[j].w
})
cnt := 0
res := 0
parent = make([]int, n)
for i := 0; i < n; i++ {
parent[i] = i
}
for i := 0; i < len(edges);i++{
pa := findpa(edges[i].st)
pb := findpa(edges[i].ed)
if pa != pb {
cnt++
res += edges[i].w
parent[pa] = pb
}
}
if cnt != n-1 {
return 0, false
}
return res, true
}