求最小生成树
题目1:寻宝
prim求最小生成树:
维护minDis数组 记录所有节点距离最小生成树的 最小距离。
依次遍历加入最小生成树, 然后更新minDis记录表。
Kruskal求最小生成树:
将边按权值从小到大排序, 然后依次加入最小生成树。
如果已经在同一个集合就不加入, 如果不在一个集合则加入。 使用并查集判断是否在同一集合。
// v 顶点数 e 边数 path[i] [a, b, val] -> ab节点相连,权重为val
// 无向有权图
// prim 算法
func minPath(v: Int, e: Int, grid: [[Int]]) -> Int {
// 最大距离为10000
var map = Array(repeating: Array(repeating: 10001, count: v + 1), count: v + 1)
// 每个节点距离最小生成树的 最小距离记录表
var minDisList = Array(repeating: 10001, count: v + 1)
// 节点是否在最小生成树里
var inTree = Array(repeating: 0, count: v + 1)
var paths = Array(repeating: 0, count: v + 1)
for path in grid {
// 无向图
map[path[0]][path[1]] = path[2]
map[path[1]][path[0]] = path[2]
}
for _ in 1...v {
// 先找距离 最小生成树 距离最近的节点,准备加入最小生成树
var cur = 0
var minDistance = Int.max
for (j, dis) in minDisList.enumerated() {
if dis < minDistance, inTree[j] == 0 {
minDistance = dis
cur = j
}
}
// 加入到最小生成树
inTree[cur] = 1
// 更新 记录表
for (j, dis) in minDisList.enumerated() {
// 当前节点不在生成树中, 并且和最近加入的树中的cur节点 做更新。
if inTree[j] == 0 && map[cur][j] < dis {
minDisList[j] = map[cur][j]
paths[j] = cur
}
}
}
paths.enumerated().forEach { print("\($0) - \($1)") }
var res = 0
for i in 2...v {
res += minDisList[i]
}
return res
}
let dis = minPath(v: 7, e: 11, grid: [[1, 2, 1], [1, 3, 1], [1, 5, 2], [2, 6, 1], [2, 4, 2], [2, 3, 2], [3, 4, 1], [4, 5, 1], [5, 6, 2], [5, 7, 1], [6, 7, 1]])
print("\(dis)")
// cruskal 算法
func minPath(v: Int, e: Int, grid: [[Int]]) -> Int {
// 将边按权值从小到大排序, 然后依次加入最小生成树。 如果已经在同一个集合就不加入, 如果不在一个集合则加入。 使用并查集判断是否在同一集合。
let grid = grid.sorted { $0[2] < $1[2] }
// 并查集
var parent = Array(repeating: 0, count: v + 1)
for i in 1...v {
parent[i] = i
}
func root(_ u: Int) -> Int {
if u == parent[u] { return u }
parent[u] = root(parent[u])
return parent[u]
}
func isSame(_ u: Int, _ v: Int) -> Bool {
root(u) == root(v)
}
func join(_ u: Int, _ v: Int) {
let u = root(u)
let v = root(v)
if u == v { return }
parent[v] = u
}
var res = 0
var paths = [[Int]]()
for edge in grid {
if isSame(edge[0], edge[1]) { continue }
join(edge[0], edge[1])
paths.append(edge)
res += edge[2]
}
paths.forEach { print("\($0[0]) - \($0[1])")}
return res
}
let dis = minPath(v: 7, e: 11, grid: [[1, 2, 1], [1, 3, 1], [1, 5, 2], [2, 6, 1], [2, 4, 2], [2, 3, 2], [3, 4, 1], [4, 5, 1], [5, 6, 2], [5, 7, 1], [6, 7, 1]])
print("\(dis)")