深度优先dfs与广度bfs优先搜索总结+例题
DFS(Deep First Search)深度优先搜索
深度优先遍历(dfs)是对一个连通图进行遍历的算法。它的思想是从一个顶点开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。
简而言之:不撞南墙不回头
模板如下:
void dfs(int t)//t代表目前dfs的深度
{
if(满足输出条件||走不下去了)
{
输出解;
return;
}
else
{
for(int i=1;i<=尝试方法数;i++)
if(满足进一步搜索条件)
{
为进一步搜索所需要的状态打上标记;
dfs(t+1);
恢复到打标记前的状态;//也就是说的{回溯一步}
}
}
}
例题一:洛谷P1219八皇后
#include<bits/stdc++.h>
using namespace std;
int a[14],b[14],c[29],d[29];//分别存横、列、左对角线、右对角线访问标记
int n;
int cnt=0;
void print()
{
cnt++;
if(cnt<=3)
{
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
}
void dfs(int k)
{
int i=k;
for(int j=1;j<=n;j++)
{
if(b[j]==0&&c[i+j]==0&&d[i-j+n]==0)//满足未被访问
{
a[i]=j;
b[j]=1;c[i+j]=1;d[i-j+n]=1;//分别在竖排,左对角线,右对角线打上标记
if(k<n)
dfs(k+1); //放置下一横排的皇后
else if(k==n)
print();
b[j]=0;c[i+j]=0;d[i-j+n]=0;//回溯,标记重新置为0
}
}
}
int main()
{
cin>>n;
dfs(1);
cout<<cnt;
return 0;
}
例题二:牛客网小雨的矩阵
#include<bits/stdc++.h>
using namespace std;
long long a[52][52];
int n;
set<int> s; //set集合中数据唯一且有序
void dfs(int x,int y,int sum){
if(x==n && y==n){
s.insert(sum); //走到(n,n)则把sum插入集合s
return;
}
if(x+1<=n){
dfs(x+1,y,sum+a[x+1][y]);//向下走
}
if(y+1<=n){
dfs(x,y+1,sum+a[x][y+1]);//向右走
}
}
int main() {
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j]; //录入矩阵
}
}
dfs(1,1,a[1][1]); //开始深搜
cout<<s.size()<<endl;//输出集合s的大小
return 0;
}
BFS(Breath First Search)广度优先搜索
广度优先搜索较之深度优先搜索之不同在于,深度优先搜索旨在不管有多少条岔路,先一条路走到底,不成功就返回上一个路口然后就选择下一条岔路,而广度优先搜索旨在面临一个路口时,把所有的岔路口都记下来,然后选择其中一个进入,然后将它的分路情况记录下来,然后再返回来进入另外一个岔路,并重复这样的操作。
简而言之:地毯式搜索或者说像水波纹一样四散开来
模板如下:
//通常用队列queue实现,或者有些时候用数组模拟队列
void bfs()
{
初始化队列q
q.push(起点);
标记上起点;
while(!q.empty())
{
取队首元素u;
q.pop();//队首元素出队
for(int i=0;i<可以走的方向数;i++)
{
if(下一步满足边界内,未访问等条件)
{
q.push();//该点入队
标记上该点;
...
}
}
}
}
例题一:洛谷P1443马的遍历
此题要求马从某点到达某点的最少要走几步,优先用bfs
#include<bits/stdc++.h>
using namespace std;
int h[8]={-2,-1,1,2,-2,-1,1,2},z[8]={1,2,2,1,-1,-2,-2,-1};//8个方向
int vis[410][410];
int cnt[410][410];//记录到达每个坐标点的步数
queue<pair<int,int> >q;
int n,m;
void bfs()
{
while(!q.empty())
{
int x=q.front().first;
int y=q.front().second;
q.pop();
for(int i=0;i<8;i++)
{
int xx=x+h[i];
int yy=y+z[i];
if(xx>n||xx<1||yy>m||yy<1||vis[xx][yy]==1)continue;//到达边界或已经访问则跳过此次循环
q.push(make_pair(xx,yy));
vis[xx][yy]=1;
cnt[xx][yy]=cnt[x][y]+1;
}
}
}
int main()
{
memset(cnt,-1,sizeof(cnt));
int x,y;
cin>>n>>m>>x>>y;
vis[x][y]=1;
cnt[x][y]=0;
q.push(make_pair(x,y));
bfs();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d",cnt[i][j]);//控制格式
}
cout<<endl;
}
return 0;
}
例题二:洛谷P1162填涂颜色
此题的关键是通过广搜把 1 外围的 0 打上标记
#include<bits/stdc++.h>
using namespace std;
int h[4]={-1,0,1,0},z[4]={0,-1,0,1};
int n,a[35][35];
queue<pair<int,int> >q;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
for(int i=0;i<=n+1;i++)//在四周加0,避免在角落的0搜不过去
{
a[0][i]=0;
a[n+1][i]=0;
a[i][0]=0;
a[n+1][i]=0;
}
q.push(make_pair(0,0));
while(!q.empty())
{
int x=q.front().first;
int y=q.front().second;
q.pop();
for(int i=0;i<4;i++)
{
int x2=x+h[i];
int y2=y+z[i];
if(x2>=0&&y2>=0&&x2<=n+1&&y2<=n+1&&a[x2][y2]==0)
{
a[x2][y2]=-1;//1外围的0标志为-1
q.push(make_pair(x2,y2));
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==-1)cout<<"0 ";
else if(a[i][j]==1)cout<<"1 ";
else if(a[i][j]==0)cout<<"2 ";
}
cout<<endl;
}
return 0;
}
综上,其实很多题dfs和bfs都可以解,但是在最短(优)路径问题上最好用广度优先bfs
深度优先dfs与广度bfs优先搜索总结+例题的更多相关文章
- 【算法入门】广度/宽度优先搜索(BFS)
广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较 ...
- java二叉树遍历——深度优先(DFS)与广度优先(BFS) 递归版与非递归版
介绍 深度优先遍历:从根节点出发,沿着左子树方向进行纵向遍历,直到找到叶子节点为止.然后回溯到前一个节点,进行右子树节点的遍历,直到遍历完所有可达节点为止. 广度优先遍历:从根节点出发,在横向遍历二叉 ...
- 【Python算法】遍历(Traversal)、深度优先(DFS)、广度优先(BFS)
图结构: 非常强大的结构化思维(或数学)模型.如果您能用图的处理方式来规范化某个问题,即使这个问题本身看上去并不像个图问题,也能使您离解决问题更进一步. 在众多图算法中,我们常会用到一种非常实用的思维 ...
- DFS+BFS(广度优先搜索弥补深度优先搜索遍历漏洞求合格条件总数)--09--DFS+BFS--蓝桥杯剪邮票
题目描述 如下图, 有12张连在一起的12生肖的邮票.现在你要从中剪下5张来,要求必须是连着的.(仅仅连接一个角不算相连) 比如,下面两张图中,粉红色所示部分就是合格的剪取. 请你计算,一共有多少 ...
- 层层递进——宽度优先搜索(BFS)
问题引入 我们接着上次“解救小哈”的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLian/p/74296 ...
- 【BFS宽度优先搜索】
一.求所有顶点到s顶点的最小步数 //BFS宽度优先搜索 #include<iostream> using namespace std; #include<queue> # ...
- BFS算法的优化 双向宽度优先搜索
双向宽度优先搜索 (Bidirectional BFS) 算法适用于如下的场景: 无向图 所有边的长度都为 1 或者长度都一样 同时给出了起点和终点 以上 3 个条件都满足的时候,可以使用双向宽度优先 ...
- 宽度优先搜索--------迷宫的最短路径问题(dfs)
宽度优先搜索运用了队列(queue)在unility头文件中 源代码 #include<iostream>#include<cstdio>#include<queue&g ...
- 算法基础⑦搜索与图论--BFS(宽度优先搜索)
宽度优先搜索(BFS) #include<cstdio> #include<cstring> #include<iostream> #include<algo ...
随机推荐
- 2 使用unitest 模块扩展功能测试
准备做一个 待办事项清单网站,来演示 Web 开发过程中的所有主要步骤.以及如何在各个步骤中运用TDD理念. ”功能测试“: 从用户的角度查看应用是如何运作的. 从某种程度上可以作为应用的说明书. 作 ...
- sql server 存储过程和视图的区别
视图 要把视图看做是一张表,包含了一张表的部分数据或者多个表的综合数据,视图的使用和普通表一样: 视图建立并存储在服务器,有效减少网络数据流量,提高安全性: 视图中不存放数据,数据依然存放在视图引用的 ...
- Security Study
1.WebGoat http://www.owasp.org.cn/ 学习Web应用漏洞最好的教程----WebGoat http://blog.csdn.net/bill_lee_sh_cn/art ...
- 7zip使用相关
造冰箱的大熊猫@cnblogs 2019/11/2 1.仅存储不压缩 7z a -mx0 compressed.7z FileFolderPath 将FileFolderPath指向的文件或文件夹打包 ...
- eclipse-jee-luna安装ADT-23.0.6出现的问题,以及解决办法
刚安装好ADT-23.0.6,然后配置sdk路径(最新的版本android-22),然后创建一个新的Android Project; 对于布局界面会出现如下错误,导致无法显示布局界面: java.la ...
- C++问题--fread文件读不完整问题解决
今天突然遇到一个问题,用fwrite/fread读写文件,发现当fread读取文件时只能读一半, 即使用foef()查看是否读到文件结尾,也是显示文件已经读取到文件末尾,查看文件的返回值发现文件只读取 ...
- VS2010调试时,对于一些语句不能单步运行也不能对变量添加监视的问题
在以mfc建立的工程中,需要建立一个链表来保存一些数据.但是在创建结构体,以及对其赋值的过程中,发现对结构体变量不能观察,添加到监视器中的变量也出现变量名不存在的错误. 首先,在文件的开始定义一个结构 ...
- CF1182F Maximum Sine【类欧,扩欧】
题目链接:洛谷 题目描述:求整数$x\in [a,b]$使得$|2px \ mod \ 2q-q|$最小,如果有多个$x$输出最小的. 数据范围:$1\leq a,b,p,q\leq 10^9$ 第一 ...
- 解决node-sass无法下载的问题
本文链接:https://blog.csdn.net/qq383366204/article/details/86605960在国内用npm安装依赖的时候经常都会有各种奇怪的问题,个人强烈推荐用yar ...
- 自制操作系统-使用16进制文件显示 hello world
1.下载qemu: https://www.cnblogs.com/sea-stream/p/10849382.html 2.制作软盘镜像 使用010editor,新建文件 图2 另保存为cherry ...