在一個的方塊城市中,座標爲的位置高度爲,有個排水井,分別位於
在一場大雨中,每個位置的水都會往相鄰的積水更低的地方流動,如果無法排出將越積越高
排水井處永遠不會積水,水不會通過城市邊緣排出(可以理解爲城市邊緣是無限高的牆)
求每個位置的積水深度
輸入描述
第一行輸入一個整數,代表有組測試數據 對於每一組測試數據,第一行輸入個整數,接下來行每行有個整數表示第行第列的高度,接下來行每行有兩個整數,表示第個排水井的位置
輸出描述
對於每組測試數據,輸出行,每行個整數,第行第列表示處的積水深度
數據範圍
輸出時每行末尾的多餘空格,不影響答案正確性
樣例輸入
2
4 1
1 2 3 4
2 3 4 3
3 4 3 2
4 3 2 1
2 2
5 2
2 2 3 2 2
2 2 3 3 3
3 3 2 2 2
2 3 2 1 1
2 3 2 1 1
4 1
3 3
樣例輸出
2 1 0 0
1 0 0 1
0 0 1 2
0 1 2 3
1 1 0 1 1
1 1 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 1
樣例解釋
第一組樣例的解釋:
第二組樣例的解釋:
首先考慮排水口,顯然排水口周圍高度非遞減的區域一定是乾的,可以bfs將這部分的水面高度更新爲的面高度,對與處於對角線的區域要單獨討論。(其實忽略也行,不過後面二分求高度會慢一點 )
然後對於沒更新的區域二分水面高度,檢查在當前水面高度是否高於鄰近已更新區域的水面高度,最後更新水面高度。
容易想錯的點是不能根據排水口的高度更新比排水口高度低的區域,因爲比排水口高度低的區域的水面高度會受到多個排水口的直接或間接影響。
爲了提高代碼效率,排水口和未更新區域要以地面從低到高順序搜索;用數組存儲標記數組標記過的位置以便還原。
時間複雜度爲。
#include<bits/stdc++.h>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 505;
int n, m, h1[N][N], h2[N][N], T;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
bool v[N][N];
vector<pair<int, pii>> seq;
vector<pii > tmp;
inline bool check(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= n;
}
inline void bfs1(int x, int y) {
if (h2[x][y])return;
queue<pii > q;
q.push({x, y}), h2[x][y] = h1[x][y];
while (!q.empty()) {
pii t = q.front();
q.pop();
repi(i, 0, 3) {
int nx = t.fi + dx[i], ny = t.se + dy[i];
if (!check(nx, ny) || h2[nx][ny] || h1[nx][ny] < h1[t.fi][t.se])continue;
h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
}
int nx = t.fi + 1, ny = t.se + 1;
if (check(nx, ny) && h1[nx][ny] >= h1[t.fi][t.se] && !h2[nx][ny] &&
(h1[t.fi + 1][t.se] <= h1[nx][ny] || h1[t.fi][t.se + 1] <= h1[nx][ny]))
h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
nx = t.fi - 1, ny = t.se + 1;
if (check(nx, ny) && h1[nx][ny] >= h1[t.fi][t.se] && !h2[nx][ny] &&
(h1[t.fi - 1][t.se] <= h1[nx][ny] || h1[t.fi][t.se + 1] <= h1[nx][ny]))
h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
nx = t.fi - 1, ny = t.se - 1;
if (check(nx, ny) && h1[nx][ny] >= h1[t.fi][t.se] && !h2[nx][ny] &&
(h1[t.fi - 1][t.se] <= h1[nx][ny] || h1[t.fi][t.se - 1] <= h1[nx][ny]))
h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
nx = t.fi + 1, ny = t.se - 1;
if (check(nx, ny) && h1[nx][ny] >= h1[t.fi][t.se] && !h2[nx][ny] &&
(h1[t.fi + 1][t.se] <= h1[nx][ny] || h1[t.fi][t.se - 1] <= h1[nx][ny]))
h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
}
}
inline bool bfs2(int x, int y, int h) {
queue<pii > q;
tmp.clear();
q.push({x, y}), tmp.pb({x, y}), v[x][y] = true;
while (!q.empty()) {
pii t = q.front();
q.pop();
repi(i, 0, 3) {
int nx = t.fi + dx[i], ny = t.se + dy[i];
if (!check(nx, ny) || v[nx][ny] || h1[nx][ny] >= h)continue;
if (h2[nx][ny]) {
for (auto it:tmp)v[it.fi][it.se] = false;
return false;
}
if (h2[nx][ny] != h)q.push({nx, ny}), tmp.pb({nx, ny}), v[nx][ny] = true;
}
}
for (auto it:tmp)v[it.fi][it.se] = false;
return true;
}
inline void change(int x, int y, int h) {
queue<pii > q;
q.push({x, y}), h2[x][y] = h;
while (!q.empty()) {
pii t = q.front();
q.pop();
repi(i, 0, 3) {
int nx = t.fi + dx[i], ny = t.se + dy[i];
if (!check(nx, ny) || h2[nx][ny])continue;
if (h1[t.fi][t.se] <= h && h1[nx][ny] <= h) {
h2[nx][ny] = h;
if (h != h1[nx][ny])q.push({nx, ny});
} else if (h1[nx][ny] >= h2[t.fi][t.se])h2[nx][ny] = h1[nx][ny], q.push({nx, ny});
}
}
}
inline void solve(int x, int y) {
int l = h1[x][y], r = 1000;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (bfs2(x, y, mid))l = mid;
else r = mid - 1;
}
change(x, y, l);
}
int main() {
T = qr();
while (T--) {
n = qr(), m = qr();
repi(i, 1, n)repi(j, 1, n)h2[i][j] = 0, v[i][j] = false;
repi(i, 1, n) repi(j, 1, n)h1[i][j] = qr();
seq.clear();
repi(i, 1, m) {
int x = qr(), y = qr();
seq.pb({h1[x][y], {x, y}});
}
sort(seq.begin(), seq.end());
for (auto it:seq) {
int x = it.se.fi, y = it.se.se;
if (v[x][y])continue;
bfs1(x, y);
}
repi(i, 1, n)repi(j, 1, n)v[i][j] = false;
seq.clear();
repi(i, 1, n)repi(j, 1, n)if (!h2[i][j])seq.pb({h1[i][j], {i, j}});
sort(seq.begin(), seq.end());
for (auto it:seq) {
int x = it.se.fi, y = it.se.se;
if (!h2[x][y])solve(x, y);
}
repi(i, 1, n) repi(j, 1, n)printf("%d%c", h2[i][j] - h1[i][j], ce(j, n));
}
return 0;
}