有 n
个网络节点,标记为 1
到 n
。
给你一个列表 times
,表示信号经过 有向 边的传递时间。 times[i] = (ui, vi, wi)
,其中 ui
是源节点,vi
是目标节点, wi
是一个信号从源节点传递到目标节点的时间。
现在,从某个节点 K
发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1
。
示例 1:
1 2
| 输入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2 输出:2
|
示例 2:
1 2
| 输入:times = [[1,2,1]], n = 2, k = 1 输出:1
|
示例 3:
1 2
| 输入:times = [[1,2,1]], n = 2, k = 2 输出:-1
|
提示:
1 <= k <= n <= 100
1 <= times.length <= 6000
times[i].length == 3
1 <= ui, vi <= n
ui != vi
0 <= wi <= 100
- 所有
(ui, vi)
对都 互不相同(即,不含重复边)
SPFA算法(链式向前星建图)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| class SPFA { final int INF = Integer.MAX_VALUE; int dists[], counts[], inQueue[]; int n, m, s, heads[], nexts[], tos[], weights[];
public SPFA(int n, int s, int edges[][]) { this.n = n; this.s = s; m = edges.length; int edgeNum = 1; dists = new int[n+1]; counts = new int[n+1]; inQueue = new int[n+1]; heads = new int[n + 1]; tos = new int[2 * m + 2]; nexts = new int[2 * m + 2]; weights = new int[2 * m + 2]; for (int[] edge : edges) { int u = edge[0], v = edge[1], w = edge[2]; ++edgeNum; nexts[edgeNum] = heads[u]; heads[u] = edgeNum; tos[edgeNum] = v; weights[edgeNum] = w; } }
public boolean bfs() { Arrays.fill(dists, INF); Deque<Integer> q = new LinkedList<>(); q.offer(s); dists[s] = 0; while (!q.isEmpty()) { int p = q.poll(); inQueue[p] = 0; for (int eg = heads[p]; eg != 0; eg = nexts[eg]) { int to = tos[eg]; if (dists[to] > dists[p] + weights[eg]) { dists[to] = dists[p] + weights[eg]; if (inQueue[to] == 0) { inQueue[to] = 1; q.offer(to); if (counts[to] > n - 1) { System.out.println("Negative Cycle Found!"); return false; } else { counts[to] += 1; } } } } } return true; } }
class Solution { public int networkDelayTime(int[][] times, int n, int k) { int res = 0; SPFA spfa = new SPFA(n, k, times); spfa.bfs(); for (int i = 1; i <= n; i++) { int dist = spfa.dists[i]; if (dist == spfa.INF) return -1; if (dist > res) res = dist; } return res; } }
|
SPFA算法(邻接表建图)
一些细节也不一样
- 这里数组大小是n,所以index要-1
- 这里直接用队列判定是否在队列中,而不是定义一个数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| class SPFA { final int INF = Integer.MAX_VALUE; int n, s, dists[], counts[]; List<int[]> g []; public SPFA(int n, int s, List<int[]> g[]) { this.n = n; this.s = s; this.g = g; this.dists = new int[n]; this.counts = new int[n]; } public boolean bfs() { Arrays.fill(dists, INF); dists[s - 1] = 0; Deque<Integer> q = new LinkedList<>(); q.add(s - 1); while (!q.isEmpty()) { int u = q.poll(); for (int vw[] : g[u]) { int v = vw[0], w = vw[1]; if (dists[u] + w < dists[v]) { dists[v] = dists[u] + w; if (!q.contains(v)) { q.add(v); if (counts[v] > n - 1) { System.out.println("Negative Cycle Found!"); return false; } else { counts[v] += 1; } } } } } return true; } } class Solution { public int networkDelayTime(int[][] times, int n, int k) { List<int[]> g[] = new ArrayList[n]; Arrays.setAll(g, i -> new ArrayList<>()); for(int[] e : times) { int u = e[0]-1, v = e[1]-1, w = e[2]; g[u].add(new int[]{v, w}); } int res = 0; SPFA spfa = new SPFA(n, k, g); spfa.bfs(); for(int dist : spfa.dists){ if(dist == spfa.INF) return -1; if(dist > res) res = dist; } return res; } }
|
Dijkstra算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int networkDelayTime(int[][] times, int n, int k) { int g[][] = new int[n][n]; for (int i = 0; i < n; i++) Arrays.fill(g[i], -1); for (int[] time : times) { int cur = time[0] - 1, next = time[1] - 1, len = time[2]; g[cur][next] = len; } int dis[] = new int[n]; Arrays.fill(dis, Integer.MAX_VALUE); PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]); dis[k - 1] = 0; pq.offer(new int[]{k-1, 0}); while (!pq.isEmpty()) { int poll[] = pq.poll(), cur = poll[0], d = poll[1]; for (int i = 0; i < n; i++) { if (g[cur][i] == -1) continue; if (d + g[cur][i] < dis[i]) { dis[i] = d + g[cur][i]; pq.offer(new int[]{i, dis[i]}); } } } int res = Arrays.stream(dis).max().getAsInt(); return res == Integer.MAX_VALUE ? -1 : res; } }
|