AcWing 173. 矩阵距离(多源BFS)

题目链接:点击这里

在这里插入图片描述
在这里插入图片描述

本题可以看作一道有多个起始状态的 flood-fill 问题。我们把矩阵 A A 每一个 1 都看作起点,整个矩阵的所有位置都可以通行,对于每个位置,在从任何一个起点出发都可以的情况下,求到达该位置所需要的最少步数(也就是距离该位置最近的起点的距离)。

在这种具有多个等价的起始状态的问题中,我们只需要在 BFS 开始之前把这些起始状态全部插入队列。根据 BFS 逐层搜索的性质,BFS 的过程就相当于每个起点先扩展 1 层,再扩展 2 层,3 层,依此类推。所以当每个位置 ( x , y ) (x,y) 第一次被访问时,就相当于距离它最近的那个起点扩展到了它,此时从那个起点到 ( x , y ) (x,y) 经历的步数就是最短距离 B [ x ] [ y ] B[x][y]

输入的 01 矩阵没有空格,所以用字符串读入。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define x first 
#define y second

using namespace std;
typedef pair<int,int> PII;
const int N = 1010, M = N * N;

int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

int n, m;
char g[N][N];
int d[N][N];
PII q[M];

void bfs()
{
    int hh = 0, tt = -1;
    memset(d, -1, sizeof d);
    
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
            if(g[i][j] == '1')
                q[++tt] = {i, j}, d[i][j] = 0;
            
    while(hh <= tt)
    {
        PII t = q[hh++];
        for(int i = 0; i < 4; ++i)
        {
            int nx = t.x + dx[i], ny = t.y + dy[i];
            
            if(nx < 0 || nx >= n || ny < 0 || ny >= m)  continue;
            if(d[nx][ny] != -1) continue;
            
            q[++tt] = {nx, ny};
            d[nx][ny] = d[t.x][t.y] + 1;
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; ++i)  scanf("%s", g[i]);
    
    bfs();
    
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)  printf("%d ", d[i][j]);
        puts("");
    }
    
    return 0;
}
发布了844 篇原创文章 · 获赞 135 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/105072801