bfs最短路与最小步数模型

bfs最短路与最小步数模型

1. 算法分析

最短路:从A点走到B点的最小距离
最小步数:从状态A到状态B的最小变化数,本质就是最短路

2. 例题

2.1 最短路

acwing1076迷宫问题
题意:
给定N*N数组,每个元素只有0和1,求从(0, 0)走到(n - 1, n - 1)的最短路,输出其路径
代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 1e3 + 10;
int a[N][N], st[N][N], n;
int pre[N * N];
queue<pair<int, int> >q;
vector<pair<int, int> > path;
int dx[4] = {
   -1, 0, 1, 0}, dy[4] = {
   0, 1, 0, -1};

void bfs(pair<int, int> start) {
   
    q.push(start);
    st[start.first][start.second] = 1;
    
    while (q.size()) {
   
        auto t = q.front();
        q.pop();
        
        for (int i = 0; i < 4; ++i) {
   
            int x = t.first + dx[i], y = t.second + dy[i];
            if (x < 0 || x > n - 1 || y < 0 || y > n - 1) continue;
            if (st[x][y] || a[x][y] == 1) continue;
            
            pre[x * n + y] = t.first * n + t.second;
            if (x == n - 1 && y == n - 1) return;
            
            st[x][y] = 1;
            q.push({
   x, y});
        }
    }
}

pair<int, int> get_pos(int x) {
   
    pair<int, int> res;
    res.first = x / n;
    res.second = x % n;
    return res;
}

int main() {
   
    cin >> n;
    for (int i = 0; i < n; ++i) 
        for (int j = 0; j < n; ++j)
            cin >> a[i][j];
    
    bfs({
   0, 0});
    int cur = (n - 1) * n + n - 1;
    while (1) {
   
        path.push_back(get_pos(cur));
        cur = pre[cur];
        if (cur == 0) break;
    }
    path.push_back({
   0, 0});
    reverse(path.begin(), path.end());
    for (auto p: path) 
        cout << p.first << " " << p.second << endl;
    return 0;
}

acwing188武士风度的牛
题意:
给定一张N*M的地图,起始地点为K,终点为H,求从K到H的最少步数
代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 160;
typedef pair<int, int> PII;
typedef pair<PII, int> PIII;
int n, m;
char mp[N][N];
int st[N][N];
PII S;

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

int bfs(){
   
    queue<PIII> q;
    q.push({
   S, 0});
    st[S.fi
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值