题目来源
题目描述
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int n, int k) {
}
};
题目解析
根据题目,从节点 k k k发出的信号,到达节点 x x x的时间就是节点 k k k到节点 x x x的最短路径的长度。因此我们需要求出节点 k k k到其余路径的最短路,其中的最大值就是答案。如果存在从 k k k触发无法到达的节点,那么就返回-1
迪杰斯特拉算法,用于计算一个节点到其他节点的最短路径
这个算法的主要思想是:贪心
- 将所有节点分为两类:已确定从起点到当前点的最短路长度的节点,以及未确定从起点到当前点的最短路长度的节点(下面简称「未确定节点」和「已确定节点」)。
- 每次[从未确定节点]中取一个与起点距离最短的点,将它归类为[已确定节点],并用它[更新]从起点到其他所有[未确定节点]的距离。直到所有点都被归类为「已确定节点」。
用节点 A「更新」节点 B 的意思是,用起点到节点 A 的最短路长度加上从节点 A 到节点 B 的边的长度,去比较起点到节点 B 的最短路长度,如果前者小于后者,就用前者更新后者。这种操作也被叫做「松弛」。
这里暗含的信息是:每次选择「未确定节点」时,起点到它的最短路径的长度可以被确定。
可以这样理解,因为我们已经用了每一个「已确定节点」更新过了当前节点,无需再次更新(因为一个点不能多次到达)。而当前节点已经是所有「未确定节点」中与起点距离最短的点,不可能被其它「未确定节点」更新。所以当前节点可以被归类为「已确定节点」。
实现1:普通堆 + 屏蔽已经计算过的点