当前位置: 首页 > article >正文

BFS——C++

BFS常使用于寻找最短路径,使用队列实现。

在学习使用BFS的时候有一难点是如何合理使用队列以及搞清楚为什么要使用队列来帮助完成BFS。

为方便理解,这里摘用一下

CodePotato

在讲解BFS的时候的图片 

这是一个树,想要通过BFS来遍历这个树的顺序应该是1->2->5->3->4->9->7->6->8->10

但是如何使用队列来完成呢?请看图片辅助理解。

首先理解了如何使用队列以及为什么要使用队列,然后通过队列的判空来控制循环,BFS其实就理解的差不多了。 

例题:https://www.acwing.com/activity/content/problem/content/907/

#include<iostream>
#include<cstring>
using namespace std;

const int N=110;
typedef pair<int,int> PII;

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

int bfs()
{
    int hh=0,tt=0;
    q[0]={0,0};//队列初始存放的是(0,0)
    
    memset(d,-1,sizeof d);//初始化距离记忆矩阵
    d[0][0]=0;
    
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    
    while(hh<=tt)
    {
        auto t=q[hh++ ];
        for(int i=0; i<4;i++)
        {  
            int x=t.first + dx[i], y=t.second + dy[i];
            if(x>=0 && y>=0 && x<n && y<m && g[x][y]==0 && d[x][y]==-1)
            {
                d[x][y]=d[t.first][t.second]+1;
                q[++tt]={x,y};
            }
            
        }
    }
    return d[n-1][m-1];
}


int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>g[i][j];
        }
   
    }
    
    cout<<bfs()<<endl;
    
    return 0;
}

例题:https://www.acwing.com/activity/content/problem/content/908/

#include<iostream>
#include <iterator>
#include<unordered_map>
#include<queue>
using namespace std;

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

//bfs思想:是把‘X’的上下左右四个位置挨个枚举
int bfs(string state){
    queue<string> q; //辅助队列
    unordered_map<string , int> d; //(最短)距离,对应题目中“(最少)交换次数”

    q.push(state); //初始状态入队列
    d[state]=0; //初始状态的距离肯定为0

    string end="12345678x";
    while(q.size()){
        auto t=q.front(); //注意,除了初始对头数据,其它都为和“x”交换后的“字符串”
        q.pop();

        if(t==end) return d[t];

        int distance=d[t];  //存储转换成t的最少交换次数
        int k=t.find('x');  //k为转后成字符串后,“x”对应的下标
        int x=k/3,y=k%3;   //字符串中的下标在3阶矩阵中对应的横纵坐标
        for(int i=0;i<4;i++){
            int a=x+dx[i],b=y+dy[i];
            if(a>=0 && a<3 && b>=0 && b<3){
                swap(t[a*3+b],t[k]); //交换字符串中两个字符
                //更新完之后的t,之前没有搜到的话
                //就要更新一下新的状态,并把他加到队列里面去
                if(!d.count(t)){ //交换之后查哈希表,发现没有之前没有出现该字符串,就将“最少交换次数”更新;
                                //那么为什么第一次交换的次数肯定是最少次数呢?因为:广度遍历是从第一层挨个往下遍历的!
                    d[t]=distance+1;
                    q.push(t);
                }
                //恢复现场
                swap(t[a*3+b],t[k]); //还有其它1~3个位置可能还没和此位置的‘x'交换
            }
        }
    }

    return -1;
}


int main(){
    string state; //初试状态
    for(int i=0;i<9;i++){
        char s;
        cin>>s;
        state+=s;
    }

    cout<<bfs(state)<<endl;

    return 0;
}


http://www.kler.cn/a/231174.html

相关文章:

  • HTTP协议笔记
  • 最大子数组和[中等]
  • 课时17:本地变量_命令变量
  • 2024-02-08 思考-楚门的世界
  • 07:Kubectl 命令详解|K8S资源对象管理|K8S集群管理(重难点)
  • 6-3、T型加减速单片机程序【51单片机+L298N步进电机系列教程】
  • 9.4 OpenGL帧缓冲:纹理和帧缓冲之间的反馈循环
  • huggingface学习|用dreambooth和lora对stable diffusion模型进行微调
  • 【JS逆向六】(上)逆向模拟生成某网站的【sig】和【payload】的值 仅供学习
  • LoveWall v2.0Pro社区型校园表白墙源码
  • 2024-02-06 TCP/UDP work
  • 国际物流数字化运输方式选择指南 | 箱讯科技
  • EMC学习笔记(二十二)降低EMI的PCB设计指南(二)
  • 代码随想录算法训练营29期Day42|卡码网46,LeetCode 416
  • 【Java EE】----Spring框架创建和使用
  • Kubernetes基础(十二)-kube-prox/CNI/服务发现(DNS域名解析)区别
  • 如何计算两个指定日期相差几年几月几日
  • VPS与云计算有什么区别?
  • 使用vite创建vue+ts项目,整合常用插件(scss、vue-router、pinia、axios等)和配置
  • CentOS7搭建Hadoop集群