【搜索】最短路模型

本文通过两个AC代码示例介绍了如何使用BFS(广度优先搜索)解决等权图中最短路径问题,包括从单源点寻找最短路和在特定条件下的最短路径。代码中强调了队列的“两段性”和“单调性”,并利用vis数组记录访问状态。此外,还展示了如何在迷宫问题和特定问题中应用BFS寻找路径。
摘要由CSDN通过智能技术生成

最短路模型

问题: BFS的最短路模型就是给我们一个等权图,问起点到终点的最短距离。


  • 当边权相等且非负时,可以用BFS寻找单源点最短路或多源点最短路。

  • bfs找最短路要保证队列“两段性”和“单调性”。



  • 代码中记录距离,可以一并压入队列,也可以使用 dis[] 数组,同时充当记录距离和标记的角色。
  • dis[] 初始化 -1 ,当 dis[i] == -1 时,表示未访问过,否则表示已访问过。

迷宫问题

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 1e3 + 10;

int n;
int a[N][N];
int pa[N][N][2];
bool vis[N][N];
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};

void print(int sx, int sy)
{
    if(sx == 0 && sy == 0){
        cout << "0 0\n";
        return ;
    }
    print(pa[sx][sy][0], pa[sx][sy][1]);
    cout << sx << " " << sy << endl;
}

int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++) cin >> a[i][j];
    
    queue<pair<int, int> >que;
    que.push({0, 0});
    vis[0][0] = 1;

    while(!que.empty())
    {
        auto t = que.front(); que.pop();
        int x = t.first, y = t.second;
        for(int i=0; i<4; i++){
            int xx = x + dx[i], yy = y + dy[i];
            if(xx < 0 || xx >= n || yy < 0 || yy >= n || a[xx][yy] == 1 || vis[xx][yy]) continue;
            vis[xx][yy] = 1;
            pa[xx][yy][0] = x, pa[xx][yy][1] = y;

            que.push({xx, yy});
        }
    }

    print(n - 1, n - 1);


    system("pause");
    return 0;
}

抓住那头牛

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 1e6 + 10;

int vis[N];

int main()
{
    int n, k;
    cin >> n >> k;
    if(n == k){ //注意,y总模板是在队头下一状态中判断是否找到终点。如果答案可能出现在初始状态中,要提前特判,或在出队时判断。
        cout << 0;
        return 0;
    }

    queue<pair<int, int> > que;
    que.push({n, 0});
    vis[n] = 1;

    while(!que.empty())
    {
        auto t = que.front(); que.pop();
        int x = t.first, dis = t.second;
        
        // 也可以在这里判断

        vector<int>ne;

        if(x + 1 < N)ne.push_back(x + 1);
        if(x - 1 >= 0) ne.push_back(x - 1);
        if(2 * x < N) ne.push_back(2 * x);

        for(auto xx : ne){
            if(xx == k){
                cout << dis + 1;
                system("pause");
                return 0;
            }
            if(vis[xx]) continue;
            vis[xx] = 1;
            que.push({xx, dis + 1});
        }
    }

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值