There are N network nodes, labelled 1 to N.
Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target.
Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1.
Example 1:
Input: times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
Output: 2
Note:
N will be in the range [1, 100].
K will be in the range [1, N].
The length of times will be in the range [1, 6000].
All edges times[i] = (u, v, w) will have 1 <= u, v <= N and 0 <= w <= 100.
给出一个有向图,每条边给出一个时间,求网络中所有点收到K发出的消息所需要的最短时间,如果有点无法到达就返回-1
思路:
即求从K点出发到所有点的最短路径,在所有最短路径中选最长的
这里用Dijkstra算法
Dijkstra算法是一种距离的relax算法,用dist(u, v)表示u到v的距离,用dist(u)表示出发点K到u的距离,那么
dist(v) = dist(u) + dist(u, v)
如果中间出现了另外一点u1,使
dist(v) > dist(u1) + dist(u1, v)
就更新 dist(v) 到新的最短距离dist(u1) + dist(u1, v)
为了更加快速更新,每更新一个最短距离,保存(u, dist[u]) 到heap中,每次取出最小的dist[u],遍历u可到达的每一个点v,更新dist(v)到新的最短路径
同时用一个数组dist,保存K到每个节点的最短距离,最后可通过遍历这个数组,找出最短路径中的最大值。dist初始化为∞,当最后仍然存在∞时,说明有点不可到达,返回-1。
Dijkstra算法
public int networkDelayTime(int[][] times, int N, int K) {
HashMap<Integer, List<int[]>> graph = new HashMap<>();
PriorityQueue<int[]> heap = new PriorityQueue<>(
(i1, i2) -> i1[1] - i2[1]);
int[] dist = new int[N+1];
int inf = 1000000000;
int result = 0;
Arrays.fill(dist, inf);
dist[K] = 0;
heap.offer(new int[]{K, 0});
//make the graph(有向图)..
for(int[] time : times) {
if(!graph.containsKey(time[0])) {
graph.put(time[0], new ArrayList<int[]>());
}
graph.get(time[0]).add(new int[]{time[1], time[2]});
}
while(!heap.isEmpty()) {
int[] nodeU = heap.poll();
int u = nodeU[0];
int distU = nodeU[1];
if(!graph.containsKey(u)) continue;
List<int[]> nodeVs = graph.get(u);
for(int[] nodeV : nodeVs) {
int v = nodeV[0];
int distUV = nodeV[1];
if(dist[v] > distU + distUV) { //dist(u) + dist(u,v)
dist[v] = distU + distUV;
heap.offer(new int[]{v, dist[v]});
}
}
}
for(int i = 1; i <= N; i++) {
if(dist[i] == inf) return -1;
result = Math.max(result, dist[i]);
}
return result;
}