3112. 访问消失节点的最少时间
给你一个二维数组 edges
表示一个 n
个点的无向图,其中 edges[i] = [ui, vi, lengthi]
表示节点 ui
和节点 vi
之间有一条需要 lengthi
单位时间通过的无向边。
同时给你一个数组 disappear
,其中 disappear[i]
表示节点 i
从图中消失的时间点,在那一刻及以后,你无法再访问这个节点。
注意,图有可能一开始是不连通的,两个节点之间也可能有多条边。
请你返回数组 answer
,answer[i]
表示从节点 0
到节点 i
需要的 最少 单位时间。如果从节点 0
出发 无法 到达节点 i
,那么 answer[i]
为 -1
。
示例 1:
输入:n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,1,5]
输出:[0,-1,4]
解释:
我们从节点 0 出发,目的是用最少的时间在其他节点消失之前到达它们。
edges[0]
到达。但当我们到达的时候,它已经消失了,所以我们无法到达它。edges[2]
到达。示例 2:
输入:n = 3, edges = [[0,1,2],[1,2,1],[0,2,4]], disappear = [1,3,5]
输出:[0,2,3]
解释:
我们从节点 0 出发,目的是用最少的时间在其他节点消失之前到达它们。
edges[0]
到达。edges[0]
和 edges[1]
到达。示例 3:
输入:n = 2, edges = [[0,1,1]], disappear = [1,1]
输出:[0,-1]
解释:
当我们到达节点 1 的时候,它恰好消失,所以我们无法到达节点 1 。
提示:
1 <= n <= 5 * 104
0 <= edges.length <= 105
edges[i] == [ui, vi, lengthi]
0 <= ui, vi <= n - 1
1 <= lengthi <= 105
disappear.length == n
1 <= disappear[i] <= 105
原站题解
rust 解法, 执行用时: 61 ms, 内存消耗: 12.2 MB, 提交时间: 2024-07-18 10:34:47
use std::collections::BinaryHeap; impl Solution { pub fn minimum_time(n: i32, edges: Vec<Vec<i32>>, disappear: Vec<i32>) -> Vec<i32> { let n = n as usize; let mut g = vec![vec![]; n]; // 邻接表 for e in edges { let x = e[0] as usize; let y = e[1] as usize; let wt = e[2]; g[x].push((y, wt)); g[y].push((x, wt)); } let mut dis = vec![-1; n]; dis[0] = 0; let mut h = BinaryHeap::new(); // 下面取相反数,变成小根堆 h.push((0, 0)); while let Some((dx, x)) = h.pop() { if -dx > dis[x] { // x 之前出堆过 continue; } for &(y, d) in &g[x] { let new_dis = -dx + d; if new_dis < disappear[y] && (dis[y] < 0 || new_dis < dis[y]) { dis[y] = new_dis; // 更新 x 的邻居的最短路 h.push((-new_dis, y)); } } } dis } }
javascript 解法, 执行用时: 699 ms, 内存消耗: 112.8 MB, 提交时间: 2024-07-18 10:34:24
/** * @param {number} n * @param {number[][]} edges * @param {number[]} disappear * @return {number[]} */ var minimumTime = function(n, edges, disappear) { const g = Array.from({length: n}, () => []); for (const [x, y, wt] of edges) { g[x].push([y, wt]); g[y].push([x, wt]); } const dis = Array(n).fill(-1); dis[0] = 0; const pq = new MinPriorityQueue({priority: (p) => p[0]}); pq.enqueue([0, 0]); while (!pq.isEmpty()) { const [dx, x] = pq.dequeue().element; if (dx > dis[x]) { // x 之前出堆过 continue; } for (let [y, wt] of g[x]) { let new_dis = dx + wt; if (new_dis < disappear[y] && (dis[y] < 0 || new_dis < dis[y])) { dis[y] = new_dis; // 更新 x 的邻居的最短路 pq.enqueue([new_dis, y]); } } } return dis; };
golang 解法, 执行用时: 217 ms, 内存消耗: 21.8 MB, 提交时间: 2024-04-15 14:25:09
func minimumTime(n int, edges [][]int, disappear []int) []int { type edge struct{ to, wt int } g := make([][]edge, n) // 稀疏图用邻接表 for _, e := range edges { x, y, wt := e[0], e[1], e[2] g[x] = append(g[x], edge{y, wt}) g[y] = append(g[y], edge{x, wt}) } dis := make([]int, n) for i := range dis { dis[i] = -1 } dis[0] = 0 h := hp{{}} for len(h) > 0 { p := heap.Pop(&h).(pair) dx := p.dis x := p.x if dx > dis[x] { // x 之前出堆过 continue } for _, e := range g[x] { y := e.to newDis := dx + e.wt if newDis < disappear[y] && (dis[y] < 0 || newDis < dis[y]) { dis[y] = newDis // 更新 x 的邻居的最短路 heap.Push(&h, pair{newDis, y}) } } } return dis } type pair struct{ dis, x int } type hp []pair func (h hp) Len() int { return len(h) } func (h hp) Less(i, j int) bool { return h[i].dis < h[j].dis } func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *hp) Push(v any) { *h = append(*h, v.(pair)) } func (h *hp) Pop() (v any) { a := *h; *h, v = a[:len(a)-1], a[len(a)-1]; return }
java 解法, 执行用时: 42 ms, 内存消耗: 104.7 MB, 提交时间: 2024-04-15 14:24:56
class Solution { public int[] minimumTime(int n, int[][] edges, int[] disappear) { List<int[]>[] g = new ArrayList[n]; // 稀疏图用邻接表 Arrays.setAll(g, i -> new ArrayList<>()); for (int[] e : edges) { int x = e[0]; int y = e[1]; int wt = e[2]; g[x].add(new int[]{y, wt}); g[y].add(new int[]{x, wt}); } int[] dis = new int[n]; Arrays.fill(dis, -1); dis[0] = 0; PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> (a[0] - b[0])); pq.offer(new int[]{0, 0}); while (!pq.isEmpty()) { int[] p = pq.poll(); int dx = p[0]; int x = p[1]; if (dx > dis[x]) { // x 之前出堆过 continue; } for (int[] e : g[x]) { int y = e[0]; int newDis = dx + e[1]; if (newDis < disappear[y] && (dis[y] < 0 || newDis < dis[y])) { dis[y] = newDis; // 更新 x 的邻居的最短路 pq.offer(new int[]{newDis, y}); } } } return dis; } }
cpp 解法, 执行用时: 375 ms, 内存消耗: 160.8 MB, 提交时间: 2024-04-15 14:24:43
class Solution { public: vector<int> minimumTime(int n, vector<vector<int>>& edges, vector<int>& disappear) { vector<vector<pair<int, int>>> g(n); // 稀疏图用邻接表 for (auto& e : edges) { int x = e[0], y = e[1], wt = e[2]; g[x].emplace_back(y, wt); g[y].emplace_back(x, wt); } vector<int> dis(n, -1); dis[0] = 0; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; pq.emplace(0, 0); while (!pq.empty()) { auto [dx, x] = pq.top(); pq.pop(); if (dx > dis[x]) { // x 之前出堆过 continue; } for (auto& [y, d] : g[x]) { int new_dis = dx + d; if (new_dis < disappear[y] && (dis[y] < 0 || new_dis < dis[y])) { dis[y] = new_dis; // 更新 x 的邻居的最短路 pq.emplace(new_dis, y); } } } return dis; } };
python3 解法, 执行用时: 255 ms, 内存消耗: 59.8 MB, 提交时间: 2024-04-15 14:24:23
# dijkstra 算法 class Solution: def minimumTime(self, n: int, edges: List[List[int]], disappear: List[int]) -> List[int]: g = [[] for _ in range(n)] # 稀疏图用邻接表 for x, y, wt in edges: g[x].append((y, wt)) g[y].append((x, wt)) dis = [-1] * n dis[0] = 0 h = [(0, 0)] while h: dx, x = heappop(h) if dx > dis[x]: # x 之前出堆过 continue for y, wt in g[x]: new_dis = dx + wt if new_dis < disappear[y] and (dis[y] < 0 or new_dis < dis[y]): dis[y] = new_dis # 更新 x 的邻居的最短路 heappush(h, (new_dis, y)) return dis