classSolution { public: staticconstint N = 50 * 50 + 2, M = 50 * 50 * 50; int he[N], e[M], ne[M], w[M], idx, n, INF = 0x3f3f3f3f; voidadd(int a, int b, int c){ e[idx] = b; ne[idx] = he[a]; w[idx] = c; he[a] = idx++; } intminPathCost(vector<vector<int>>& grid, vector<vector<int>>& moveCost){ int N = grid.size(), M = grid[0].size(); int S = N * M, T = S + 1; n = N * M + 2; fill(he, he + n, -1); //「虚拟源点」向「第一行」进行连边 for (int i = 0; i < M; i++) add(S, grid[0][i], grid[0][i]); // 转换原图 for (int i = 0; i < N - 1; i++) { for (int j = 0; j < M; j++) { int a = grid[i][j]; for (int k = 0; k < M; k++) { int b = grid[i + 1][k]; add(a, b, moveCost[a][k] + b); } } } //「最后一行」向「虚拟汇点」进行连边 for (int i = 0; i < M; i++) add(grid[N - 1][i], T, 0); // 最短路 vector<int> dist = dijkstra(S); return dist[T]; } vector<int> dijkstra(int x){ vector<int> dist(n, 0x3f3f3f3f); vector<bool> vis(n, false); dist[x] = 0; // 使用「优先队列」存储所有可用于更新的点 // 以 (到起点的距离, 点编号) 进行存储,优先弹出「最短距离」较小的点 priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; q.push({0, x}); while (!q.empty()) { // 每次从「优先队列」中弹出 auto [step, u] = q.top(); q.pop(); // 如果弹出的点被标记「已更新」,则跳过 if (vis[u]) continue; // 标记该点「已更新」,并使用该点更新其他点的「最短距离」 vis[u] = true; for (int i = he[u]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] <= dist[u] + w[i]) continue; dist[j] = dist[u] + w[i]; q.push({dist[j], j}); } } return dist; } };
classSolution: defminPathCost(self, grid, moveCost): N, M = len(grid), len(grid[0]) S, T = N * M, N * M + 1 n = N * M + 2 he = [-1] * n e, ne, w = [-1] * (50 * 50 * 50), [-1] * (50 * 50 * 50), [-1] * (50 * 50 * 50) idx = 0
defadd(a, b, c): nonlocal idx e[idx] = b ne[idx] = he[a] w[idx] = c he[a] = idx idx += 1
defdijkstra(x): dist = [float('inf')] * n vis = [False] * n dist[x] = 0 # 使用「优先队列」存储所有可用于更新的点 # 以 (到起点的距离, 点编号) 进行存储,优先弹出「最短距离」较小的点 q = [(0, x)] heapq.heapify(q) while q: # 每次从「优先队列」中弹出 step, u = heapq.heappop(q) # 如果弹出的点被标记「已更新」,则跳过 if vis[u]: continue # 标记该点「已更新」,并使用该点更新其他点的「最短距离」 vis[u] = True i = he[u] while i != -1: j, c = e[i], w[i] i = ne[i] if dist[j] <= dist[u] + c: continue dist[j] = dist[u] + c heapq.heappush(q, (dist[j], j)) return dist
#「虚拟源点」向「第一行」进行连边 for i inrange(M): add(S, grid[0][i], grid[0][i]) # 转换原图 for i inrange(N - 1): for j inrange(M): a = grid[i][j] for k inrange(M): b = grid[i + 1][k] add(a, b, moveCost[a][k] + b) #「最后一行」向「虚拟汇点」进行连边 for i inrange(M): add(grid[N - 1][i], T, 0) # 最短路 dist = dijkstra(S) return dist[T]
classSolution { public: intminPathCost(vector<vector<int>>& grid, vector<vector<int>>& moveCost){ int m = grid.size(), n = grid[0].size(), INF = 0x3f3f3f3f, ans = INF; vector<vector<int>> dist(m, vector<int>(n, INF)); priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq; for (int i = 0; i < n; i++) { pq.push({0, i, grid[0][i]}); dist[0][i] = grid[0][i]; } while (!pq.empty()) { vector<int> info = pq.top(); pq.pop(); int x = info[0], y = info[1], cur = info[2]; if (x == m - 1) { ans = min(ans, cur); continue; } for (int i = 0; i < n; i++) { int step = moveCost[grid[x][y]][i], ne = grid[x + 1][i]; int tot = cur + step + ne; if (tot >= ans || dist[x + 1][i] <= tot) continue; dist[x + 1][i] = tot; pq.push({x + 1, i, tot}); } } return ans; } };
classSolution: defminPathCost(self, grid, moveCost): m, n, INF = len(grid), len(grid[0]), float('inf') ans = INF dist = [[INF] * n for _ inrange(m)] for i inrange(n): dist[0][i] = grid[0][i] pq = [(0, i, grid[0][i]) for i inrange(n)] while pq: x, y, cur = heapq.heappop(pq) if x == m - 1: ans = min(ans, cur) continue for i inrange(n): step, ne = moveCost[grid[x][y]][i], grid[x + 1][i] tot = cur + step + ne if tot >= ans or dist[x + 1][i] <= tot: continue dist[x + 1][i] = tot heapq.heappush(pq, (x + 1, i, tot)) return ans
classSolution { publicintminPathCost(int[][] grid, int[][] moveCost) { intm= grid.length, n = grid[0].length, INF = 0x3f3f3f3f, ans = INF; for (inti= m - 2; i >= 0; i--) { for (intj=0; j < n; j++) { intcur= INF; for (intk=0; k < n; k++) cur = Math.min(cur, grid[i + 1][k] + moveCost[grid[i][j]][k]); grid[i][j] += cur; } } for (inti=0; i < n; i++) ans = Math.min(ans, grid[0][i]); return ans; } }
C++ 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { public: intminPathCost(vector<vector<int>>& grid, vector<vector<int>>& moveCost){ int m = grid.size(), n = grid[0].size(), INF = INT_MAX, ans = INF; for (int i = m - 2; i >= 0; i--) { for (int j = 0; j < n; j++) { int cur = INF; for (int k = 0; k < n; k++) cur = min(cur, grid[i + 1][k] + moveCost[grid[i][j]][k]); grid[i][j] += cur; } } for (int i = 0; i < n; i++) ans = min(ans, grid[0][i]); return ans; } };
Python 代码:
1 2 3 4 5 6 7
classSolution: defminPathCost(self, grid, moveCost): m, n = len(grid), len(grid[0]) for i inrange(m - 2, -1, -1): for j inrange(n): grid[i][j] += min([grid[i + 1][k] + moveCost[grid[i][j]][k] for k inrange(n)]) returnmin([grid[0][i] for i inrange(n)])
TypeScript 代码:
1 2 3 4 5 6 7 8 9 10 11 12
functionminPathCost(grid: number[][], moveCost: number[][]): number { let m = grid.length, n = grid[0].length, INF = 0x3f3f3f3f, ans = INF; for (let i = m - 2; i >= 0; i--) { for (let j = 0; j < n; j++) { let cur = INF; for (let k = 0; k < n; k++) cur = Math.min(cur, grid[i + 1][k] + moveCost[grid[i][j]][k]); grid[i][j] += cur; } } for (let i = 0; i < n; i++) ans = Math.min(ans, grid[0][i]); return ans; };