【算法题解】拜访 (BFS)

拜访

原题描述

现在有一个城市销售经理,需要从公司出发,去拜访市内的某位商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他每次移动只能在左右中选择一个方向 或 在上下中选择一个方向,现在问他有多少种最短方案到达商家地址。

给定一个地图 CityMap 及它的 行长度 n 和 列长度 m ,其中1代表经理位置, 2 代表商家位置, -1 代表不能经过的地区, 0 代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于 10。

注意:需保证所有方案的距离都是最短的方案

数据范围: 2 ≤ n , m ≤ 10 2 \leq n,m \leq 10 2n,m10

例如当输入为[[2,0,0,0],[0,-1,-1,0],[0,-1,1,0],[0,0,0,0]],4,4时,对应的4行4列CityMap如下图所示:

img

经理的位置在(2,2),商家的位置在(0,0),经分析,经理到达商家地址的最短方案有两种,分别为:

(2,2)->(2,3)->(1,3)->(0,3)->(0,2)->(0,1)->(0,0)

(2,2)->(3,2)->(3,1)->(3,0)->(2,0)->(1,0)->(0,0),所以对应的返回值为2

示例1

输入:

[[0,1,0],[2,0,0]],2,3

返回值:

2

示例2

输入:

[[2,0,0,0],[0,-1,-1,0],[0,-1,1,0],[0,0,0,0]],4,4

返回值:

2

BFS

  • BFS可以进行最短路的搜索,这题在此基础上稍微进行了改动

  • 遍历过得节点标记 − 1 -1 1防止重复遍历,但是对于中点不需要标记,否则第二次到达无法辨识是终点

  • min_dis记录最短的距离,min_cnt记录有多少条最短路

  • 结构体TII定义了地图点坐标以及从起点到达该点的距离,其邻接节点在其基础上+1

  • 注意下一个节点的位置要判断是否越界

#include <bits/stdc++.h>

#define debug

#define x first
#define y second
using namespace std;

struct TII {
    int x, y, dis;
};

int countPath(vector<vector<int> > &CityMap, int n, int m) {
 	queue<TII> q;
    int dx[] = {0, -1, 0, 1}, dy[] = {-1, 0, 1, 0};
    //找起点
    TII st;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (CityMap[i][j] == 1) {
                st = {i, j, 0};
                break;
            }
        }
    }
    //BFS搜索
    q.push(st);
    CityMap[st.x][st.y] = -1;
    int min_dis = 0x3f3f3f3f;
    int min_cnt = 0;

    while (!q.empty()) {
        TII tmp = q.front();
        q.pop();
        cout << tmp.x << ' ' << tmp.y << endl;
        if (CityMap[tmp.x][tmp.y] == 2) {
            if (tmp.dis < min_dis) {
                min_cnt = 1;
                min_dis = tmp.dis;
            } else if (tmp.dis == min_dis) { min_cnt++; }
        } else {
            CityMap[tmp.x][tmp.y] = -1;//标记已经走过,终点不能标记,否则第二次到达无法判断
            //将邻接的点加入队列
            for (int i = 0; i < 4; ++i) {
                int xi = tmp.x + dx[i], yi = tmp.y + dy[i];
                if (xi < 0 || xi >= n || yi < 0 | yi >= m)continue;
                if (CityMap[xi][yi] != -1) {
                    q.push({xi, yi, tmp.dis + 1});
                }
            }
        }
    }
    return min_cnt;
}
int main() {
#ifdef debug
    freopen("in.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n >> m;
    vector<vector<int>> g(n, vector<int>(m));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> g[i][j];
        }
    }
    cout << '@' << countPath(g, n, m) << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011459717/article/details/128613646
BFS