离线+优先队列优化 BFS
考虑暴力。
对于每次查询,将第一行放入队列中,然后逐步向外拓展。
时间复杂度 。
分析可得,毒的强度越强,能杀死的苯就越多。
那么可以考虑将所有的查询存下来,从小到大排序。
然后用一个优先队列(小根堆)存被污染的苯,初始值为第一行。
随后开始遍历所有查询,对于每个查询进行 bfs。
此时的 bfs 不再是从头开始,而是接着上次的 bfs 继续搜索,直到搜索到当前的苯生命值大于毒的强度。
#include <bits/stdc++.h>
using namespace std;
struct query
{
int x, i;
bool operator<(const query &b) const
{
return x < b.x;
}
};
struct node
{
int x, y, val;
node() {}
node(int x, int y, int k) : x(x), y(y), val(k) {}
bool operator<(const node &b) const
{
return val > b.val;
}
};
void _()
{
int n, m, q;
cin >> n >> m >> q;
vector<vector<int>> a(n + 7, vector<int>(m + 7)), in(n + 7, vector<int>(m + 7));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
vector<query> ask(q);
for (int i = 0; i < q; i++)
{
cin >> ask[i].x;
ask[i].i = i;
}
sort(ask.begin(), ask.end());
array<int, 4> dx = {0, 0, 1, -1},
dy = {1, -1, 0, 0};
priority_queue<node> h;
for (int i = 1; i <= m; i++)
{
h.push(node(1, i, a[1][i]));
in[1][i] = 1;
}
int sum = 0;
vector<int> ans(q);
for (int qwq = 0; qwq < q; qwq++)
{
while (h.size())
{
auto [x, y, k] = h.top();
if (k > ask[qwq].x)
break;
h.pop(), sum++;
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i], yy = y + dy[i];
if (xx < 1 || xx > n || yy < 1 || yy > m || in[xx][yy])
continue;
h.push(node(xx, yy, a[xx][yy]));
in[xx][yy] = 1;
}
}
ans[ask[qwq].i] = sum;
}
for (auto i : ans)
cout << i << '\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
_();
return 0;
}

京公网安备 11010502036488号