d793: 00929 - Number Maze

Tags: dijkstra, graph


出處:https://zerojudge.tw/ShowProblem?problemid=d793
提交:https://zerojudge.tw/Submissions?problemid=d793&account=allllllan123456


問題:給定一個 $N\in[1,999]$ 乘以 $M\in[1,999]$ 的迷宮,每一格都有一個介於 0 到 9 的整數,請問從最左上角走到最右下角所經過的方格數字總和的最小值為何?


解法:因為這題的邊成本沒有負數,我們可以使用 Dijkstra’s 演算法求解。如何從迷宮轉為有向圖?我們可以視最左上角的數字為從出發點走至該格的成本,之後每當我從 A 格走到 B 格,就把這個過程當成一個有向邊而且其權重便為 B 格的數字,這樣也是一張合法的有向圖。


 1#include <bits/stdc++.h>
 2using namespace std;
 3
 4typedef pair<int, int> pii;
 5
 6int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); // IO 優化
 7    priority_queue<pii, vector<pii>, greater<pii>> pq;
 8    char m[999][999]; int T, dist[999*999]; cin >> T;
 9    while (T--) { int N, M; cin >> N >> M;
10        for (int i=0; i<N; i++)
11            for (int j=0; j<M; j++)
12                cin >> m[i][j], m[i][j] -= '0';
13        memset(dist, 0x7f, sizeof dist);
14        dist[0] = m[0][0];
15        pq.push(pii(dist[0], 0));
16        while (!pq.empty()) {
17            int u = pq.top().second; pq.pop();
18            int dx[] = {-1,1,0,0}, dy[] = {0,0,-1,1};
19            for (int i=0; i<4; i++) {
20                int x = u/M + dx[i], y = u%M + dy[i];
21                if (0<=x && x<N && 0<=y && y<M) {
22                    int v = x * M + y;
23                    if (dist[v] > dist[u] + m[x][y])
24                        dist[v] = dist[u] + m[x][y],
25                        pq.push(pii(dist[v], v));
26                }
27            }
28        }
29        cout << dist[N*M-1] << '\n';
30    }
31    return 0;
32}

no image