-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDijkstra.cpp
More file actions
111 lines (92 loc) · 2.48 KB
/
Copy pathDijkstra.cpp
File metadata and controls
111 lines (92 loc) · 2.48 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <bits/stdc++.h>
#define _ \
ios_base::sync_with_stdio(0); \
cin.tie(0);
#define endl '\n'
#define pb push_back
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;
struct Offset {
int dr, dc;
int dist;
};
void solve() {
int h, w;
if (!(cin >> h >> w)) return;
vector<string> grid(h);
for (int i = 0; i < h; i++) {
cin >> grid[i];
}
int start_r, start_c, end_r, end_c;
cin >> start_r >> start_c >> end_r >> end_c;
start_r--; start_c--; end_r--; end_c--;
vector<vector<int>> dist(h, vector<int>(w, INF));
vector<vector<bool>> vis(h, vector<bool>(w, false));
vector<Offset> offsets;
for (int r = -3; r <= 3; r++) {
for (int c = -3; c <= 3; c++) {
int d = abs(r) + abs(c);
if (d > 0 && d <= 3) {
offsets.push_back({r, c, d});
}
}
}
dist[start_r][start_c] = 0;
deque<pair<int, int>> dq;
dq.push_front({start_r, start_c});
int adj_dr[] = {1, -1, 0, 0};
int adj_dc[] = {0, 0, 1, -1};
while (!dq.empty()) {
auto curr = dq.front();
dq.pop_front();
int u = curr.first;
int v = curr.second;
if (vis[u][v]) continue;
vis[u][v] = true;
if (u == end_r && v == end_c) break;
// 0-cost transitions: normal moves to adjacent road cells
for (int i = 0; i < 4; i++) {
int nu = u + adj_dr[i];
int nv = v + adj_dc[i];
if (nu >= 0 && nu < h && nv >= 0 && nv < w) {
if (grid[nu][nv] == '.') {
if (dist[u][v] < dist[nu][nv]) {
dist[nu][nv] = dist[u][v];
dq.push_front({nu, nv});
}
}
}
}
// 1-cost transitions: front kicks
for (const auto& opt : offsets) {
int nu = u + opt.dr;
int nv = v + opt.dc;
if (nu >= 0 && nu < h && nv >= 0 && nv < w) {
bool is_reachable = false;
if (grid[nu][nv] == '#') {
if ((opt.dr == 0 || opt.dc == 0) && opt.dist <= 2) {
is_reachable = true;
}
} else {
is_reachable = true;
}
if (is_reachable) {
if (dist[u][v] + 1 < dist[nu][nv]) {
dist[nu][nv] = dist[u][v] + 1;
dq.push_back({nu, nv});
}
}
}
}
}
cout << dist[end_r][end_c] << endl;
}
int main() {
_
solve();
return 0;
}