AT_abc348_d 题解

思路

优先队列 BFS。首先肯定对于每个位置,能量值越大越优,优先队列中按照当前能量值从大到小排序,然后只要比当前最优解更优时可以入队,最后如果到了终点就结束了。

另一种解法

因为可以重复进队,所以用普通队列也行。但是普通队列会导致重复进队次数太多辣,所以虽然优先队列有 log\log,但普通队列效率远远不及优先队列。

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
struct node {
	int x, y, z;
	bool operator < (const node& t) const {
		return z < t.z;
	}
} ;
int n, m, t, x, y, z, a[205][205], vis[205][205];
string mp[205];
priority_queue <node> q;
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> n >> m;
	for (int i = 0; i < n; ++ i)
		cin >> mp[i];
	cin >> t;
	while (t --)
		cin >> x >> y >> z, a[x - 1][y - 1] = z;
	for (int i = 0; i < n; ++ i)
		for (int j = 0; j < m; ++ j) {
			vis[i][j] = -1;
			if (mp[i][j] == 'S') {
				q.push ({i, j, a[i][j]});
				vis[i][j] = a[i][j];
			}
		}
	while (! q.empty ()) {
		const node x = q.top ();
		if (mp[x.x][x.y] == 'T') {
			cout << "Yes";
			return 0;
		}
		q.pop ();
		if (x.z)
			for (int i = 0; i < 4; ++ i) {
				int X = dx[i] + x.x, Y = dy[i] + x.y, Z = max (x.z - 1, a[X][Y]);
				if (~X && ~Y && X < n && Y < m && Z > vis[X][Y] && mp[X][Y] != '#') {
					vis[X][Y] = Z;
					q.push ({X, Y, Z});
				}
			}
	}
	cout << "No";
	return 0;
}
posted @ 2024-04-07 15:14  Vitamin_B  阅读(7)  评论(0)    收藏  举报  来源