链接:https://ac.nowcoder.com/acm/contest/75630
E-小红勇闯地下城
思路
dijkstra模版题,把击杀怪物的血量看作边权,计算起点到终点的最短路,如果路径长度大于等于生命值,则能够安全到达终点。(比赛时居然没想到,一直在BFS,图论太差了T_T)
代码
#include <bits/stdc++.h>
using namespace std;
int q, n, m, h, dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
struct Comparator {
bool operator()(const array<int, 3>& a, const array<int, 3>& b) {
return a[2] > b[2];
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> q;
while (q--) {
cin >> n >> m >> h;
int tx, ty;
vector<string> v(n);
vector<vector<int>> dis(n, vector<int>(m, INT_MAX));
vector<vector<bool>> vis(n, vector<bool>(m, false));
priority_queue<array<int, 3>, vector<array<int, 3>>, Comparator> pq;
for (int i = 0; i < n; i++) {
cin >> v[i];
for (int j = 0; j < m; j++) {
if (v[i][j] == 'S') {
v[i][j] = '0';
dis[i][j] = 0;
pq.push({i, j, 0});
} else if (v[i][j] == 'T') {
tx = i;
ty = j;
v[i][j] = '0';
}
}
}
while (!pq.empty()) {
auto a = pq.top();
pq.pop();
if (vis[a[0]][a[1]]) {
continue;
}
vis[a[0]][a[1]] = true;
for (auto& d : dir) {
int x = a[0] + d[0], y = a[1] + d[1];
if (0 <= x && x < n && 0 <= y && y < m &&
dis[x][y] > dis[a[0]][a[1]] + v[x][y] - '0') {
dis[x][y] = dis[a[0]][a[1]] + v[x][y] - '0';
if (!vis[x][y]) {
pq.push({x, y, dis[x][y]});
}
}
}
}
if (dis[tx][ty] >= h) {
cout << "No\n";
} else {
cout << "Yes\n";
}
}
return 0;
}