97. 小明逛公园
题目描述
小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短的路径。
给定一个公园景点图,图中有 N 个景点(编号为 1 到 N),以及 M 条双向道路连接着这些景点。每条道路上行走的距离都是已知的。
小明有 Q 个观景计划,每个计划都有一个起点 start 和一个终点 end,表示他想从景点 start 前往景点 end。由于小明希望节省体力,他想知道每个观景计划中从起点到终点的最短路径长度。 请你帮助小明计算出每个观景计划的最短路径长度。
输入描述
第一行包含两个整数 N, M, 分别表示景点的数量和道路的数量。
接下来的 M 行,每行包含三个整数 u, v, w,表示景点 u 和景点 v 之间有一条长度为 w 的双向道路。
接下里的一行包含一个整数 Q,表示观景计划的数量。
接下来的 Q 行,每行包含两个整数 start, end,表示一个观景计划的起点和终点。
输出描述
对于每个观景计划,输出一行表示从起点到终点的最短路径长度。如果两个景点之间不存在路径,则输出 -1。
输入示例
7 3
2 3 4
3 6 6
4 7 8
2
2 3
3 4
输出示例
4
-1
提示信息
从 2 到 3 的路径长度为 4,3 到 4 之间并没有道路。
1 <= N, M, Q <= 1000.
思路:
本题是多源最短路,即 求多个起点到多个终点的多条最短路径
最短路算法-Floyd 算法
Floyd 算法对边的权值正负没有要求,都可以处理。
1、确定dp数组(dp table)以及下标的含义
这里我们用 grid数组来存图,那就把dp数组命名为 grid。
grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合为中间节点的最短距离为m
2、确定递推公式
在上面的分析中我们已经初步感受到了递推的关系。
我们分两种情况:
- 节点i 到 节点j 的最短路径经过节点k
- 节点i 到 节点j 的最短路径不经过节点k
对于第一种情况,grid[i][j][k] = grid[i][k][k - 1] + grid[k][j][k - 1]
节点i 到 节点k 的最短距离 是不经过节点k,中间节点集合为[1...k-1],所以 表示为grid[i][k][k - 1]
节点k 到 节点j 的最短距离 也是不经过节点k,中间节点集合为[1...k-1],所以表示为 grid[k][j][k - 1]
第二种情况,grid[i][j][k] = grid[i][j][k - 1]
如果节点i 到 节点j的最短距离 不经过节点k,那么 中间节点集合[1...k-1],表示为 grid[i][j][k - 1]
因为我们是求最短路,对于这两种情况自然是取最小值。
即: grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])
3、dp数组如何初始化
grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合为中间节点的最短距离为m。
刚