拓扑排序 和 最短路径
题目1:拓扑排序
每次找入度为0的点,然后移除它。 依次进行就是 节点的顺序就是 遵循依赖的。
func tuopuSort(n: Int, m: Int, grid: [[Int]]) {
// 入度统计
var digree = Array(repeating: 0, count: n)
// 结果
var res = [Int]()
// 邻接表统计依赖关系
var map = Array(repeating: [Int](), count: n)
for i in grid {
let s = i[0]
let t = i[1]
map[s].append(t)
digree[t] += 1
}
print("\(digree)")
print("\(map)")
var queue = [Int]()
for (i, d) in digree.enumerated() {
if d == 0 {
queue.append(i)
}
}
while !queue.isEmpty {
let node = queue.removeFirst()
res.append(node)
for i in map[node] {
digree[i] -= 1
if digree[i] == 0 {
queue.append(i)
}
}
}
if res.count == n {
res.forEach { print("\($0)") }
} else {
print("-1")
}
}
tuopuSort(n: 5, m: 4, grid: [[0, 1], [0, 2], [1, 3], [2, 4]])
题目2:最短路径
dijkstra算法, 类似于prim算法。
这里求的有向有权图。
维护minDis列表,每次选择最近的点加入已访问列表, 然后更新minDis列表。 依次进行。
最后minDis里面的值 即是每个元素距离起点最短的路径。
func minPathInDirectionMap(n: Int, e: Int, grid: [[Int]]) {
var visited = Array(repeating: 0, count: n + 1)
// 记录每个点 距离源点的最小距离
var minDis = Array(repeating: Int.max, count: n + 1)
var map = Array(repeating: Array(repeating: Int.max, count: n + 1), count: n + 1)
for i in grid {
map[i[0]][i[1]] = i[2]
}
// 源点距离为0
minDis[1] = 0
var path = Array(repeating: -1, count: n + 1)
// 遍历N轮
for _ in 1...n {
// 1. 取最近节点
// 2. 标记为已访问
// 3. 更新minDis数组
var cur = 1
var minVal = Int.max
for i in 1...n {
if visited[i] == 0, minDis[i] < minVal {
minVal = minDis[i]
cur = i
}
}
visited[cur] = 1
for i in 1...n {
if visited[i] == 0, map[cur][i] != Int.max, minDis[cur] + map[cur][i] < minDis[i] {
minDis[i] = minDis[cur] + map[cur][i]
// 这里 会有未被用到的路径 被记录进来。
path[i] = cur
}
}
}
if minDis[n] == Int.max {
print("无法到达终点")
} else {
print("\(minDis[n])")
path.enumerated().forEach { print("\($1) -> \($0)")}
}
}
minPathInDirectionMap(n: 7, e: 9, grid:[[1, 2, 1], [1, 3, 4], [2, 3, 2], [2, 4, 5], [3, 4, 2], [4, 5, 3], [2, 6, 4], [5, 7, 4], [6, 7, 9]])