01矩阵-【BFS】

01矩阵

给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。两个相邻元素间的距离为 1 ,方格斜方向不计算距离。

示例 1:
输入:

[0 0 0
0 1 0
0 0 0]

输出:

[0 0 0
0 1 0
0 0 0]

示例 2:
输入:

[0 0 0
0 1 0
1 1 1]

输出:

[0 0 0
0 1 0
1 2 1]

注意:

给定矩阵的元素个数不超过 10000。
给定矩阵中至少有一个元素是 0。
矩阵中的元素只在四个方向上相邻: 上、下、左、右。

思路:

对每个值为0的点进行bfs,不断更新最短路径,因为元素个数不超过10000所以最长距离也就是199,先把res[][]数组的值设置成205即可,

记得要加标记数组,防止重复访问,会陷入死循环,我第一次就是忘记加了。 对0进行bfs搜索要比对1进行bfs搜索要好,因为前者更方便剪枝。

#include <iostream>
#include <math.h>
#include <queue>
#include <string.h>
using namespace std;

// 方向数组 上右下左
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
// 地图
int nums[105][105];
// 是否访问过   0代表没访问过,1代表访问过
int vis[105][105];
// 结果
int res[105][105];
// 地图长度
int n;

bool check(int x, int y)
{
    // 判断在界内,并且没被访问过,并且值为1。(值为0的话,肯定是从0这个点向其他点扩展,比原先的点更近一点)
    return x >= 0 && y >= 0 && x < n && y < n && vis[x][y] == 0 && nums[x][y] == 1;
}

void bfs(int x, int y)
{
    res[x][y] = 0;
    queue<pair<int, int>> q;
    memset(vis, 0, sizeof(vis));
    vis[x][y] = 1; //设置(x,y)访问过
    q.push({x, y});

    while (!q.empty())
    {
        // len++;
        pair<int, int> t = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            int newx = t.first + dx[i];
            int newy = t.second + dy[i];
            if (check(newx, newy))
            {
                // 将新点标记访问过
                vis[newx][newy] = 1;
                // 上一个点的长度+1,便是bfs层数。    刷新最短距离。
                res[newx][newy] = min(res[t.first][t.second] + 1, res[newx][newy]);
                q.push({newx, newy});
            }
        }
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> nums[i][j];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            res[i][j] = 205;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (nums[i][j] == 0)
                bfs(i, j);

    cout << endl;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            cout << res[i][j] << " ";
        cout << endl;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/52dxer/p/12843026.html