100276. 最短路径中的边
给你一个 n
个节点的无向带权图,节点编号为 0
到 n - 1
。图中总共有 m
条边,用二维数组 edges
表示,其中 edges[i] = [ai, bi, wi]
表示节点 ai
和 bi
之间有一条边权为 wi
的边。
对于节点 0
为出发点,节点 n - 1
为结束点的所有最短路,你需要返回一个长度为 m
的 boolean 数组 answer
,如果 edges[i]
至少 在其中一条最短路上,那么 answer[i]
为 true
,否则 answer[i]
为 false
。
请你返回数组 answer
。
注意,图可能不连通。
示例 1:
输入:n = 6, edges = [[0,1,4],[0,2,1],[1,3,2],[1,4,3],[1,5,1],[2,3,1],[3,5,3],[4,5,2]]
输出:[true,true,true,false,true,true,true,false]
解释:
以下为节点 0 出发到达节点 5 的 所有 最短路:
0 -> 1 -> 5
:边权和为 4 + 1 = 5
。0 -> 2 -> 3 -> 5
:边权和为 1 + 1 + 3 = 5
。0 -> 2 -> 3 -> 1 -> 5
:边权和为 1 + 1 + 2 + 1 = 5
。示例 2:
输入:n = 4, edges = [[2,0,1],[0,1,1],[0,3,4],[3,2,2]]
输出:[true,false,false,true]
解释:
只有一条从节点 0 出发到达节点 3 的最短路 0 -> 2 -> 3
,边权和为 1 + 2 = 3
。
提示:
2 <= n <= 5 * 104
m == edges.length
1 <= m <= min(5 * 104, n * (n - 1) / 2)
0 <= ai, bi < n
ai != bi
1 <= wi <= 105
原站题解
golang 解法, 执行用时: 266 ms, 内存消耗: 17.7 MB, 提交时间: 2024-04-21 23:58:50
func findAnswer(n int, edges [][]int) []bool { type edge struct{ to, w, i int } g := make([][]edge, n) for i, e := range edges { x, y, w := e[0], e[1], e[2] g[x] = append(g[x], edge{y, w, i}) g[y] = append(g[y], edge{x, w, i}) } dis := make([]int, n) for i := 1; i < n; i++ { dis[i] = math.MaxInt } h := hp{{}} for len(h) > 0 { p := heap.Pop(&h).(pair) x := p.x if p.dis > dis[x] { continue } for _, e := range g[x] { y := e.to newD := p.dis + e.w if newD < dis[y] { dis[y] = newD heap.Push(&h, pair{newD, y}) } } } ans := make([]bool, len(edges)) // 图不连通 if dis[n-1] == math.MaxInt { return ans } // 从终点出发 BFS vis := make([]bool, n) vis[n-1] = true q := []int{n - 1} for len(q) > 0 { y := q[0] q = q[1:] for _, e := range g[y] { x := e.to if dis[x]+e.w != dis[y] { continue } ans[e.i] = true if !vis[x] { vis[x] = true q = append(q, x) } } } return ans } 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 }
golang 解法, 执行用时: 256 ms, 内存消耗: 16.9 MB, 提交时间: 2024-04-21 23:58:39
func findAnswer(n int, edges [][]int) []bool { type edge struct{ to, w, i int } g := make([][]edge, n) for i, e := range edges { x, y, w := e[0], e[1], e[2] g[x] = append(g[x], edge{y, w, i}) g[y] = append(g[y], edge{x, w, i}) } // Dijkstra 算法模板 dis := make([]int, n) for i := 1; i < n; i++ { dis[i] = math.MaxInt } h := hp{{}} for len(h) > 0 { p := heap.Pop(&h).(pair) x := p.x if p.dis > dis[x] { continue } for _, e := range g[x] { y := e.to newD := p.dis + e.w if newD < dis[y] { dis[y] = newD heap.Push(&h, pair{newD, y}) } } } ans := make([]bool, len(edges)) // 图不连通 if dis[n-1] == math.MaxInt { return ans } // 从终点出发 DFS vis := make([]bool, n) var dfs func(int) dfs = func(y int) { vis[y] = true for _, e := range g[y] { x := e.to if dis[x]+e.w != dis[y] { continue } ans[e.i] = true if !vis[x] { dfs(x) } } } dfs(n - 1) return ans } 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 }
cpp 解法, 执行用时: 454 ms, 内存消耗: 165.9 MB, 提交时间: 2024-04-21 23:58:24
class Solution { public: vector<bool> findAnswer(int n, vector<vector<int>>& edges) { vector<vector<tuple<int, int, int>>> g(n); for (int i = 0; i < edges.size(); i++) { auto& e = edges[i]; int x = e[0], y = e[1], w = e[2]; g[x].emplace_back(y, w, i); g[y].emplace_back(x, w, i); } vector<long long> dis(n, LLONG_MAX); dis[0] = 0; priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq; pq.emplace(0, 0); while (!pq.empty()) { auto [dx, x] = pq.top(); pq.pop(); if (dx > dis[x]) { continue; } for (auto [y, w, _] : g[x]) { int new_dis = dx + w; if (new_dis < dis[y]) { dis[y] = new_dis; pq.emplace(new_dis, y); } } } vector<bool> ans(edges.size()); // 图不连通 if (dis[n - 1] == LLONG_MAX) { return ans; } // 从终点出发 BFS vector<int> vis(n); vis[n - 1] = true; queue<int> q; q.push(n - 1); while (!q.empty()) { int y = q.front(); q.pop(); for (auto [x, w, i] : g[y]) { if (dis[x] + w != dis[y]) { continue; } ans[i] = true; if (!vis[x]) { vis[x] = true; q.push(x); } } } return ans; } // bfs vector<bool> findAnswer2(int n, vector<vector<int>>& edges) { vector<vector<tuple<int, int, int>>> g(n); for (int i = 0; i < edges.size(); i++) { auto& e = edges[i]; int x = e[0], y = e[1], w = e[2]; g[x].emplace_back(y, w, i); g[y].emplace_back(x, w, i); } vector<long long> dis(n, LLONG_MAX); dis[0] = 0; priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq; pq.emplace(0, 0); while (!pq.empty()) { auto [dx, x] = pq.top(); pq.pop(); if (dx > dis[x]) { continue; } for (auto [y, w, _] : g[x]) { int new_dis = dx + w; if (new_dis < dis[y]) { dis[y] = new_dis; pq.emplace(new_dis, y); } } } vector<bool> ans(edges.size()); // 图不连通 if (dis[n - 1] == LLONG_MAX) { return ans; } // 从终点出发 DFS vector<int> vis(n); function<void(int)> dfs = [&](int y) { vis[y] = true; for (auto [x, w, i] : g[y]) { if (dis[x] + w != dis[y]) { continue; } ans[i] = true; if (!vis[x]) { dfs(x); } } }; dfs(n - 1); return ans; } };
java 解法, 执行用时: 65 ms, 内存消耗: 80.6 MB, 提交时间: 2024-04-21 23:57:33
class Solution { public boolean[] findAnswer(int n, int[][] edges) { List<int[]>[] g = new ArrayList[n]; Arrays.setAll(g, i -> new ArrayList<>()); for (int i = 0; i < edges.length; i++) { int[] e = edges[i]; int x = e[0], y = e[1], w = e[2]; g[x].add(new int[]{y, w, i}); g[y].add(new int[]{x, w, i}); } long[] dis = new long[n]; Arrays.fill(dis, Long.MAX_VALUE); dis[0] = 0; PriorityQueue<long[]> pq = new PriorityQueue<>((a, b) -> Long.compare(a[0], b[0])); pq.offer(new long[]{0, 0}); while (!pq.isEmpty()) { long[] dxPair = pq.poll(); long dx = dxPair[0]; int x = (int) dxPair[1]; if (dx > dis[x]) { continue; } for (int[] t : g[x]) { int y = t[0]; int w = t[1]; long newDis = dx + w; if (newDis < dis[y]) { dis[y] = newDis; pq.offer(new long[]{newDis, y}); } } } boolean[] ans = new boolean[edges.length]; // 图不连通 if (dis[n - 1] == Long.MAX_VALUE) { return ans; } // 从终点出发 BFS boolean[] vis = new boolean[n]; vis[n - 1] = true; Queue<Integer> q = new ArrayDeque<>(); q.offer(n - 1); while (!q.isEmpty()) { int y = q.poll(); for (int[] t : g[y]) { int x = t[0]; int w = t[1]; int i = t[2]; if (dis[x] + w != dis[y]) { continue; } ans[i] = true; if (!vis[x]) { vis[x] = true; q.offer(x); } } } return ans; } }
java 解法, 执行用时: 65 ms, 内存消耗: 81.6 MB, 提交时间: 2024-04-21 23:57:20
class Solution { public boolean[] findAnswer(int n, int[][] edges) { List<int[]>[] g = new ArrayList[n]; Arrays.setAll(g, i -> new ArrayList<>()); for (int i = 0; i < edges.length; i++) { int[] e = edges[i]; int x = e[0], y = e[1], w = e[2]; g[x].add(new int[]{y, w, i}); g[y].add(new int[]{x, w, i}); } long[] dis = new long[n]; Arrays.fill(dis, Long.MAX_VALUE); dis[0] = 0; PriorityQueue<long[]> pq = new PriorityQueue<>((a, b) -> Long.compare(a[0], b[0])); pq.offer(new long[]{0, 0}); while (!pq.isEmpty()) { long[] dxPair = pq.poll(); long dx = dxPair[0]; int x = (int) dxPair[1]; if (dx > dis[x]) { continue; } for (int[] t : g[x]) { int y = t[0]; int w = t[1]; long newDis = dx + w; if (newDis < dis[y]) { dis[y] = newDis; pq.offer(new long[]{newDis, y}); } } } boolean[] ans = new boolean[edges.length]; // 图不连通 if (dis[n - 1] == Long.MAX_VALUE) { return ans; } // 从终点出发 DFS boolean[] vis = new boolean[n]; dfs(n - 1, g, dis, ans, vis); return ans; } private void dfs(int y, List<int[]>[] g, long[] dis, boolean[] ans, boolean[] vis) { vis[y] = true; for (int[] t : g[y]) { int x = t[0]; int w = t[1]; int i = t[2]; if (dis[x] + w != dis[y]) { continue; } ans[i] = true; if (!vis[x]) { dfs(x, g, dis, ans, vis); } } } }
python3 解法, 执行用时: 468 ms, 内存消耗: 57.8 MB, 提交时间: 2024-04-21 23:57:04
class Solution: # Dijkstra 算法 + DFS def findAnswer(self, n: int, edges: List[List[int]]) -> List[bool]: g = [[] for _ in range(n)] for i, (x, y, w) in enumerate(edges): g[x].append((y, w, i)) g[y].append((x, w, i)) # Dijkstra 算法模板 dis = [inf] * n dis[0] = 0 h = [(0, 0)] while h: dx, x = heappop(h) if dx > dis[x]: continue for y, w, _ in g[x]: new_dis = dx + w if new_dis < dis[y]: dis[y] = new_dis heappush(h, (new_dis, y)) ans = [False] * len(edges) # 图不连通 if dis[-1] == inf: return ans # 从终点出发 DFS vis = [False] * n def dfs(y: int) -> None: vis[y] = True for x, w, i in g[y]: if dis[x] + w != dis[y]: continue ans[i] = True if not vis[x]: dfs(x) dfs(n - 1) return ans # Dijkstra 算法 + BFS def findAnswer2(self, n: int, edges: List[List[int]]) -> List[bool]: g = [[] for _ in range(n)] for i, (x, y, w) in enumerate(edges): g[x].append((y, w, i)) g[y].append((x, w, i)) # Dijkstra 算法模板 dis = [inf] * n dis[0] = 0 h = [(0, 0)] while h: dx, x = heappop(h) if dx > dis[x]: continue for y, w, _ in g[x]: new_dis = dx + w if new_dis < dis[y]: dis[y] = new_dis heappush(h, (new_dis, y)) ans = [False] * len(edges) # 图不连通 if dis[-1] == inf: return ans # 从终点出发 BFS vis = [False] * n vis[-1] = True q = deque([n - 1]) while q: y = q.popleft() for x, w, i in g[y]: if dis[x] + w != dis[y]: continue ans[i] = True if not vis[x]: vis[x] = True q.append(x) return ans