AcWing 3083. 矩阵距离
原题链接
简单
/*小白又一次被算法的魅力所惊叹了,
原题的计算思路是从每一个点出发,利用DFS深度优先遍历,寻找距离其最近的数字1,
显然会进行很多重复运算,
采用多源DFS算法,从每一个数字1散射出发(有一种从终点开始,逆向进行的感觉),
计算到其周围数字0的距离,最先遍历到的一定就是最短距离。
太优美了!!!*/
#include <iostream>
#include <cstring>
using namespace std;
const int N=1010;
int m,n;
int dist[N][N],g[N][N]; //dist存距离,g存储原始矩阵
typedef pair<int,int> PII;
PII q[N*N]; //队列辅助进行DFS算法
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; //上下左右前进
void bfs(){
memset(dist,-1,sizeof dist); //dist初始化为-1,若值为-1,则未遍历过,需要进行处理
int hh=0,tt=-1; //队列初始化
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]==1){ //将矩阵中所有1入队,多源同时处理
q[++tt]={i,j};
dist[i][j]=0;
}
}
}
while(hh<=tt){
PII t=q[hh++]; //取队头
int a=t.first,b=t.second;
for(int i=0;i<4;i++){
int x=a+dx[i],y=b+dy[i]; //上下左右行进
if(x>=0&&x<n&&y>=0&&y<m&&dist[x][y]==-1){
dist[x][y]=dist[a][b]+1;
q[++tt]={x,y}; //入队
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%1d",&g[i][j]); //每次只能读入一个整型变量
}
}
bfs(); //BFS深度优先遍历
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
printf("%d ",dist[i][j]);
}
printf("\n");
}
return 0;
}