参考算法竟赛进阶指南——李煜东
本题可以看做一道有多个起始点的flood-fill问题,把第一个矩阵中的每个1都看作是一个起始点,整个矩阵都可以通行,对于每个位置,在从任何一个起点出发都可以到达的情况下,求到达该位置的最小步数(即距离该位置最近的起点的距离)
在这样的问题中,可以在bfs开始之前把所有起始点放进队列,再根据bfs逐层搜索的性质,会从起点不断扩展1层,两层。。。
知道遍历完整个数组
代码:
#include<bits/stdc++.h>
using namespace std;
const int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
int n,m;
char a[1010][1010];
int b[1010][1010];
queue<pair<int,int> > q;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%s",a[i]+1);
/* for(int i=1;i<=n;i++)
{for(int j=1;j<=m;j++)
cout<<a[i][j];
cout<<endl;}*/
memset(b,-1,sizeof(b));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]=='1') q.push(make_pair(i,j)),b[i][j]=0;
while(q.size())
{ pair<int,int> now =q.front();
// cout<<now.first<<" "<<now.second<<endl;
q.pop();
for(int i=0;i<4;i++)
{ pair<int,int> next(now.first+dx[i],now.second+dy[i]);
if(next.first<1||next.second<1||next.first>n||next.second>m)
continue;
if(b[next.first][next.second]==-1)
{ b[next.first][next.second]=b[now.first][now.second]+1;
q.push(next);}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cout<<b[i][j]<<" ";
cout<<endl;}
}