173. 矩阵距离(多源BFS,超级原点)
给定一个 N 行 M 列的 0101 矩阵 A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:
dist(A[i][j],A[k][l])=|i−k|+|j−l|
输出一个 N 行 M 列的整数矩阵 B,其中:
B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])
输入格式
第一行两个整数 N,M
接下来一个 N 行 M 列的 0101 矩阵,数字之间没有空格。
输出格式
一个 N 行 M 列的矩阵 B,相邻两个整数之间用一个空格隔开。
数据范围
1≤N,M≤1000
输入样例:
3 4
0001
0011
0110
输出样例:
3 2 1 0
2 1 0 0
1 0 0 1
解析 :
我们可以将所有得 1 作为起点,这样用bfs遍历即可得到任何一个点到1 得最短距离(超级原点思想)。
我们首先需将所有得1 先入栈
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e3 + 5;
int n, m;
char g[N][N];
int v[N][N],d[N][N];
void bfs() {
queue<PII>q;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (g[i][j] == '1') {
q.push({ i,j });
v[i][j] = 1;
}
}
}
int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
while (!q.empty()) {
PII t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int a = t.first + dx[i], b = t.second + dy[i];
if (a <= 0 || a > n || b <= 0 || b > m)continue;
if (v[a][b])continue;
q.push({ a,b });
v[a][b] = 1;
d[a][b] = d[t.first][t.second] + 1;
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
scanf("%s", g[i] + 1);
}
bfs();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
printf("%d ", d[i][j]);
}
printf("\n");
}
return 0;
}