BFS(宽度优先搜索、广度优先搜索)_bfs csdn-程序员宅基地

技术标签: 算法  Acwing算法基础  宽度优先  

宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止 。

 

BFS算法常用于求最短路径或者求扩散性质的区域问题。

(1)走迷宫最短路径

(2)数字按规则转换的最少次数

(3)棋盘上某个棋子N步后能到达的位置总数

(4)病毒扩散计算

(5)图像中连通块的计算。

模板

可以分为四个步骤:初始化(初始化队列和所求的值) -> 判空取队头(判断是否为空并取出队头) -> 拓展(利用队头去扩展)->依次四个方向 -> 判断入队(如果符合,将该点入队)。

void bfs(){
	queue<int>q;
    //此处定义一个哈希map存距离或者定义全局二维数组存距离
	q.push(初始位置);
    //初始位置距离赋值0
	int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//四个方向上的向量
	
	while(q.size()){
        auto t = q.front();
        q.pop();//取出队头的点,用该点向周围扩散。
		for(int i=0;i<4;i++){
            int a=   ,b=  
            if(check(j)){       //如果该点可行就将它加入队列中
            q.push(j);		
            //实施相应的操作 
            }
        }
	} 
} 

 

#include<bits/stdc++.h>
using namespace std;
const int N=110;
typedef pair<int ,int> PII;
int n,m;
int g[N][N];//存放地图
int d[N][N];//存放该点到起点的距离

int bfs(){
	queue<PII> q;
	memset(d, -1 ,sizeof d);//将值全部初始化为-1 代表还没有走过
	d[0][0]=0;//第一个点已经走过
	q.push({0,0});//将起点插入队列中
    int dx[4]={-1,0,1,0},dy[4]={0,1,0,-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&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==-1){//x、y符合条件 该位置为0 且没有走过
				d[x][y]=d[t.first][t.second]+1;//离起点距离加 1
				q.push({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;
}

 解析点这

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

int bfs(string start) {
	string end="12345678x";//完成时的字符串
	queue<string> q;
	unordered_map<string,int > d; //存放某个字符串到起点的距离
	q.push(start);//将字符串插入队列
	d[start]=0;//到起点的距离为0
	int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};//四个方向上的向量
	while(q.size()){//对列不为空
		auto t=q.front();
		q.pop();//弹出对头
		int distance=d[t];
		if(t==end) return distance;//相等则返回距离
		//一维数组转化为二维数组的技巧
		int k=t.find('x');//查找x所在的下标
		int x=k/3,y=k%3;//转化为2维数组时的下标
		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){//如果a,b没有越界
				swap(t[k],t[a*3+b]);//把x和要走的位置 互换一下
				if(!d.count(t)){//如果当前位置没有走过  每次四个方向判断完后都被弹出了  下次再走时已经不存在
					d[t]=distance+1;
					q.push(t);
				}
				swap(t[k],t[a*3+b]);//把位置还原 继续判断下一个方向
			}
		}
	}
	return -1;
}
int main() {
	char c;
	string start;
	for(int i=0; i<9; i++) {
		cin>>c;
		start+=c;//字符的拼接
	}
	cout<<bfs(start)<<endl;
	return 0;
}

套模板是如此的简单 直接上代码 

#include<bits/stdc++.h>
using namespace std;
const int N=110;
typedef pair<int,int> PII;
int g[N][N];
int d[N][N];
int n,m;
int x3,y3,x2,y2;//y0,y1与math头文件有冲突 不能用
int bfs(int x3,int y3,int x2,int y2){
    bool st=false;
    memset(d,-1,sizeof(d));
    d[x3][y3]=0;
    queue<PII> q;
    q.push({x3,y3});
    while(q.size()){
        auto t=q.front();
        if(t.first==x2&&t.second==y2) st=true;
        q.pop();
        int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
        for(int i=0;i<4;i++){
            int x=t.first+dx[i],y=t.second+dy[i];
            if(x>=1&&x<=n&&y>=1&&y<=m&&d[x][y]==-1&&g[x][y]==1){
                d[x][y]=d[t.first][t.second]+1;
                q.push({x,y});
            }
        }
    }
   if(st) return d[x2][y2];
    return -1;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>g[i][j];
    cin>>x3>>y3>>x2>>y2;
    cout<<bfs(x3,y3,x2,y2)<<endl;
}

 

 也可以说是bfs吧

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N][N];
char b[N][N];
int n,m,k;

void bfs(){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        b[i][j]=a[i][j];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(b[i][j]=='g'){
                if(i-1>=1)
                a[i-1][j]='g';
                if(i+1<=n)
                a[i+1][j]='g';
                if(j-1>=1)
                a[i][j-1]='g';
                if(j+1<=m)
                a[i][j+1]='g';
            }
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>a[i][j];
    cin>>k;
    while(k--){
        bfs();
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<a[i][j];
        }
        cout<<endl;
    }
    return 0;
}

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

string start,ed;
int len;

int bfs(){
    unordered_map <string,int>dist;
    dist[start] = 0;
    queue<string> q;
    q.push(start);
    while(q.size()){
        auto t = q.front();
        q.pop();
        int distance = dist[t];
        if(t==ed) return distance;
        int dx[6] = {1,-1,2,-2,3,-3};
        
        int k = t.find('*');
        for(int i = 0;i < 6;i++){
            int x = k + dx[i];
            if(x >= 0 && x < len){
                swap(t[k],t[x]);
                if(!dist.count(t)){
                    dist[t] = distance + 1;
                    q.push(t);
                }
                swap(t[k],t[x]);
            }
        }
    }
    return -1;
}

int main(){
    cin>>start>>ed;
    len=start.size();
    cout << bfs() << endl;
    return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_53515812/article/details/127323248

智能推荐

vue+h5做的App使用api进行文件的下载自动安装打开_h5+vue实现apk下载并自动打开-程序员宅基地

文章浏览阅读5.1k次。 本人第一次写博客,菜鸟一只,也不大会用语言表述,写博客只是单纯记录下自己遇到的问题,并且记录下来以便日后使用的时候可以有个思路。如果能够帮助到别人就更好了。 现在公司的项目需要用vue做一个安卓app,需要实现app的自动更新功能。我的设计方案就是打开App先提交请求到后台,需要更新会返回下载地址。创建下载的代码: // 下载最新版本 JX_do..._h5+vue实现apk下载并自动打开

JfreeChart将图形输出到jsp页面_jfreechart画图返回给浏览器-程序员宅基地

文章浏览阅读4.3k次。1.web.xml中加入以下配置信息. DisplayChart org.jfree.chart.servlet.DisplayChart DisplayChart /DisplayChart 2.jfreeChart.jsp<%@ page_jfreechart画图返回给浏览器</div>

JQuery 基本选择器-程序员宅基地

文章浏览阅读489次。.imgclass { width:250px; height:250px; } .imgclass1 { width:210px; height:210px; } table tr td { width

WebView的使用详解-程序员宅基地

文章浏览阅读2.4w次,点赞7次,收藏38次。WebView现在Android开发基本都会用到WebView,所以自己准备系统的整理下,供自己学习之用. 这是我的WebViewDemo的GitHub地址.是一个带有顶部进度条WebView的小Demo,可以去看下~~1.简介WebView是一个基于webkit引擎、展现web页面的控件。 Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chr_webview

Halcon算子学习——图像阈值分割算子_halcon histo_to_thresh-程序员宅基地

文章浏览阅读1.5k次。图像二值化是图像分析与处理中最常见最重要的处理手段,二值处理方法也非常多。越精准的方法计算量也越大。一、threshold-全局固定阈值分割threshold(Image : Region : MinGray, MaxGray : )使用全局固定阈值分割图像,阈值从输入图像中选取灰度值g满足以下条件的像素点满足条件的图像的所有点作为一个区域返回。如果传递多个灰度值间隔(MinGray和MaxGray的元组),则每个间隔返回一个单独的区域。对于向量场图像,阈值不应用于灰度值,而是应用于向量_halcon histo_to_thresh

#C语言程序设计——程序与程序设计语言#_1.c 语言中对一些标识符规定了专门的用途,如int,if,while,case等,它们(能、不-程序员宅基地

文章浏览阅读1.4k次,点赞31次,收藏16次。计算机最基本的处理数据的单元就是计算机的指令,同时一系列计算机指令的有序组合就构成了程序。下面是计算机系统常见的7条指令:假设该计算机指令系统的指令名(如 Store, Add 等),以及所涉及的数据X,Y,Z,P等。指令一:Input X;将当前数据储存到X单元中指令二:Output X;将X单元中的数据输出指令三:Add X Y Z;将X与Y中的数据相加并储存到Z中指令四:Sub X Y Z;将X与Y中的数据相减并储存到Z中指令五。_1.c 语言中对一些标识符规定了专门的用途,如int,if,while,case等,它们(能、不

随便推点

oracle查询trim没有生效,TRIM指令真的生效了吗?TRIMcheck软件帮你查-程序员宅基地

文章浏览阅读444次。拼 命 加 载 中 ...越来越多的玩家已经开始用上了SSD固态硬盘,也感受到了开机如飞的感觉了吧,不过因为使用原理的不同,SSD依然有一些问题很烦人,比如P/E擦写次数有限,越用越慢,恢复SSD性能除了靠主控的GC垃圾回收机制,还可以借助系统的TRIM指令。有关TRIM指令的介绍可以参考我们去年的SSD固态硬盘横评,里面介绍的很详细了。用户可以自行检查TRIM指令开启与否,打开CMD窗口定位到“..._trimcheck

吉林大学软件学院大二上c++课设(黑白框模拟QQ通信——数据库,CS架构,多线程,socket通信)_模拟qq软件,基于多线程编程技术捕捉笔记本摄像头或麦克风实时数据,基于socket-程序员宅基地

文章浏览阅读100次。黑白框模拟QQ通信——数据库,CS架构,多线程,socket通信_模拟qq软件,基于多线程编程技术捕捉笔记本摄像头或麦克风实时数据,基于socket

Docker学习之安装docker-compose命令(采用Python-pip命令安装)_docker compose pip安装-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏7次。Docker学习之安装docker-compose命令:采用Python-pip命令安装本机系统环境介绍Docker Compose简介使用Python-pip命令进行安装第一步:环境检查第二步:安装Python-pip第三步:安装docker-compose第四步:检查是否安装成功第五步:通过pip命令卸载docker-compose本机系统环境介绍Ubuntu系统环境介绍介绍Ubunt..._docker compose pip安装

python百度贴吧发帖签到_python 爬虫 百度贴吧签到小工具-程序员宅基地

文章浏览阅读99次。import requests,re,timeheader ={"Cookie":"登陆过账号后的cookie 必须填写","User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"}#访问个人帐号下的贴吧主页..._贴吧签到获取tbs失败

C/C++——编译器 GCC与LLVM_gcc llvm-程序员宅基地

文章浏览阅读5.2k次,点赞4次,收藏14次。C类型语言的各种编译器,比如(gcc clang)编译器有关的名词:GNU,GCC,CLANG,LLVM等编译器简单地说,编译器可以看作是一个语言翻译器。就像把中文翻译成英语一样,编译器可以把高级语言翻译成计算机能够执行的机器语言。这样看来,GCC可以算得上是一个精通多国语言的高级翻译官了。最简单的GCC使用指令如下所示:gcc hello.c -o helloGCC接受hel..._gcc llvm

TDOA-GDOP计算_tdoa gdop-程序员宅基地

文章浏览阅读306次,点赞2次,收藏4次。TDOA-GDOP计算背景TDOA定位是一种利用时间差进行定位的方法。通过测量信号到达监测站的时间,可以确定信号源的距离。利用信号源到各个监测站的距离(以监测站为中心,距离为半径作圆),就能确定信号的位置。一个目标点:E(x,y,z)E(x,y,z)E(x,y,z)四个测向站:S0(x0,y0,z0),S1(x1,y1,z1),S2(x2,y2,z2),S3(x3,y3,z3),S_0(x_0,y_0,z_0),S_1(x_1,y_1,z_1),S_2(x_2,y_2,z_2),S_3(x_3,y__tdoa gdop

推荐文章

热门文章

相关标签