题目描述
有 n 个网络节点,标记为 1 到 n。
给你一个列表 times,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi),其中 ui 是源节点,vi 是目标节点, wi 是一个信号从源节点传递到目标节点的时间。
现在,从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1 。
样例描述
输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
输出:2
思路
- 本题“从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号”可转化为求从k点出发,到所有其他点的最短距离中的最大值。
- 朴素Dijkstra算法
代码
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
//图
int g[][] = new int[n + 1][n + 1];
int dist[] = new int[n + 1];
final int INF = 0x3f3f3f3f;
boolean visit[] = new boolean[n + 1];
//图的初始化
for (int i = 1; i <= n; i ++ ) {
Arrays.fill(g[i], INF);
}
Arrays.fill(visit, false);
Arrays.fill(dist, INF);
//图的构造 补充边的信息
for (int t[]: times) {
int u = t[0], v = t[1], w = t[2];
g[u][v] = w;
}
//下面为 Dijkstra算法
dist[k] = 0; //k为源点,求k到其他所有点的最短路径
for (int p = 1; p <= n; p ++ ) {
int t = -1; //保存距离i最近的点
//没访问过,并且比dist[i]更小,就更新 注意t初始值为-1 不更新
for (int i = 1; i <= n; i ++ ) {
if (!visit[i] && (t == -1 || dist[i] < dist[t])) t = i;
}
visit[t] = true;
//遍历所有结点 看是否会通过t结点更新最短距离
for (int j = 1; j <= n; j ++ ) {
dist[j] = Math.min(dist[j], dist[t] + g[t][j]);
}
}
//求所有最短距离里面的最大的
//注意不要用for each形式,会把dist[0]算进去,导致结果一直为INF! 很隐蔽的BUG!
int res = -1;
for (int i = 1; i <= n; i ++ ) {
res = Math.max(res, dist[i]);
}
return res > INF / 2 ? -1 : res;
}
}