题目链接: GYM - 101572 E
题目大意
n*m的地图, 每个格子有一个海拔高度, 海拔<0的地方有水, 现在在(x, y)最深处放一个抽水机, 问最多能抽多少水, 水只能从高出往低处流
思路
一开始我想到用普通队列BFS, 但是因为水可以往八个方向流, 如果先出队列的不出最深的一个点的话, 原本能流过去的水可能就流不过去了, 所以用优先队列, 保证先出队列的是当前已处理的最深的节点
代码
Accepted 124 ms 5200 KB
#include <bits/stdc++.h>
using namespace std;
const int maxn = 600;
int s[maxn][maxn], n, m;
bool vist[maxn][maxn];
int dx[] = {1, -1, 0, 0, -1, -1, 1, 1};
int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
struct P
{
int x, y;
P(int i, int j):x(i), y(j) {}
P(){}
bool operator < (const P&b) const
{
return s[x][y] > s[b.x][b.y];
}
};
int main()
{
cin >> n >> m;
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j) scanf("%d", &s[i][j]);
int x, y;
scanf("%d%d", &x, &y);
--x, --y;
priority_queue<P> que;
que.push(P(x, y));
vist[x][y] = 1;
while(!que.empty())
{
P now = que.top(); que.pop();
for(int i=0; i<8; ++i)
{
int nx = now.x + dx[i];
int ny = now.y + dy[i];
if(0<=nx && nx<n && 0<=ny && ny<m && !vist[nx][ny])
{
vist[nx][ny] = 1;
s[nx][ny] = max(s[now.x][now.y], s[nx][ny]);
que.push(P(nx, ny));
}
}
}
long long ans = 0;
for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) if(s[i][j] < 0) ans += -s[i][j];
cout << ans << endl;
return 0;
}