前言

这篇原本是两个搜索算法,但是发现BFS那个单独看的人多,所以这篇改为单独的DFS,建议先看完BFS

简介

深度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一。其别名又叫DFS,其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次,但在类似迷宫的问题中效率较低。

迷宫

还是以好理解的迷宫举例子
0是路,1是墙,2是入口,3是出口
0 0 1 0 1
2 1 0 0 3
0 0 0 1 0
0 1 0 1 0
0 1 0 0 0
也就是

把走过的路标记为2
那么来看下DFS是怎么走的
开始上图
从起点一个方向走到头

死路,那么后退直到有别的方向

继续

那么你可能就会问了,这不对啊,最短路明明是走上面啊
别急,这就是它走迷宫效率不高的原因,他有很多种走到终点的方法,但是不一定是最快的,这有时候取决于你的方向设定,也许某个顺序你就能蒙到最短路,但往往没这可能,所以我们可以让他把所有路走一遍,比较出那个最短的
DFS的精髓就在于return,利用好递归以及条件的判定

代码

上面问题的代码(到了就行,不一定最短)

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;int m,n,sum=0,ok=1;  //看下面
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; //看我!看我!看我!方向可以自己改改看有什么效果
int Map[5][5]; //看过了,回上面
int l,t=0;
vector<pair<int,int> > q;bool judge(int x1,int y1){//判边界return (x1>=0&&x1<=4&&y1>=0&&y1<=4&&(Map[x1][y1]==0||Map[x1][y1]==3));
}
void dfs(int x,int y){if(ok)//到了就不跑了,后面全过return;for(int i=0;i<4;i++){int x1 = x+dir[i][0];int y1 = y+dir[i][1];if(judge(x1,y1)){if(Map[x1][y1]==3){  //到终点ok=1;cout << sum<<endl;return;}Map[x1][y1]=2;for(int i=0; i<5; i++){      //打印地图for(int j=0; j<5; j++)cout << Map[i][j];cout << endl;}cout << endl;pair<int,int> z(x1,y1);q.push_back(z);sum++;dfs(x1,y1);if(ok)return;Map[x1][y1]=0;for(int i=0; i<5; i++){      //打印地图for(int j=0; j<5; j++)cout << Map[i][j];cout << endl;}cout << endl;q.pop_back();sum--;}}
}
int main()
{int sx,sy;ok = 0;for(int i=0;i<=4;i++){for(int j=0;j<=4;j++){cin>>Map[i][j];if(Map[i][j]==2){sx = i;sy = j;}}}pair<int,int> z(sx,sy);q.push_back(z);dfs(sx,sy);return 0;
}

例题

1.来个迷宫练练手

例题链接

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;int m,n;
int vis[5][5];
int f[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int a[5][5];
int l,t=0;
vector<pair<int,int> > q;
vector<pair<int,int> > q2;bool judge(int x1,int y1){return (x1>=0&&x1<=4&&y1>=0&&y1<=4&&vis[x1][y1]==0&&a[x1][y1]==0);
}
void dfs(int x,int y){if(x == 4&&y== 4){if(t==0|| q2.size()>q.size()){t = 1;l = q.size();q2.clear();for(int i=0;i<q.size();i++){q2.push_back(q[i]);}}return ; }for(int i=0;i<4;i++){int x1 = x+f[i][0];int y1 = y+f[i][1];if(judge(x1,y1)){vis[x1][y1]=1;pair<int,int> z(x1,y1);q.push_back(z);dfs(x1,y1);vis[x1][y1]=0;q.pop_back();}}}
int main()
{memset(a,0,sizeof a);memset(vis,0,sizeof vis);for(int i=0;i<=4;i++){for(int j=0;j<=4;j++){cin>>a[i][j];}}vis[0][0]=1;pair<int,int> z(0,0);q.push_back(z);dfs(0,0);for(int i=0;i<l;i++){cout << "(" << q2[i].first << ", " << q2[i].second << ")";if(i!=l-1)cout << endl;}return 0;
}

那么问题又来了,既然这样我为什么要用麻烦的DFS?
这是因为BFS由于同步走,也就意味着同步存储,当数据量过大时,占用的空间将是很大的量,一些题是会超内存的。(聪明反被聪明误?)同样道理,DFS相当于遍历,因此总是会超时间。(太耿直了也不行啊)

2.遍历

题目链接

依旧简单的一题!

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;int m,n,p;
int a[10][10];
int b[10][10];
int vis[10][10];
int f[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},2,1,2,-1,1,-2,-1,-2};
vector<pair<int,int> > q;
int xb,yb,xe,ye,sum=0;
bool judge(int x1,int y1){return (x1>=0&&x1<m&&y1>=0&&y1<n&&vis[x1][y1]==0);
}
void dfs(int x,int y){//    cout<<"x1: "<<x<<"   y1:"<<y<<endl;p=1;for(int i=0;i<m;i++){for(int l=0;l<n;l++){if(vis[i][l]==0){p=0;break;break;}}}if(p){sum++;return ;}for(int i=0;i<8;i++){int x1 = x+f[i][0];int y1 = y+f[i][1];if(judge(x1,y1)){vis[x1][y1]=1;pair<int,int> z(x1,y1);q.push_back(z);dfs(x1,y1);vis[x1][y1]=0;q.pop_back();}}}
int main()
{int o;cin >> o;while(o--){sum = 0;memset(vis,0,sizeof (vis));cin>>m>>n;cin>>xb>>yb;vis[xb][yb]=1;pair<int,int> z(xb,yb);q.push_back(z);dfs(xb,yb);cout << sum << endl;}return 0;
}

3.一个找不到的题目

貌似是计蒜客的,大概复述一下,你可以自己造点数据

给你一串字符,输出变化后的样子,给几个例子(不保证完全和原题一样,只能说差不多)

3(h)->hhh
2(2(a)b)->2(aab)->aabaab
b1(2(an)a)->banana

你可以自己搞更多重,我偷个懒 ̄ω ̄=

4.救救小狗

之前说过这个玩意时间复杂度会很高,那么一个很必要的技巧就是剪枝,也就是提前结束无用过程,祝你时间达标hhh
题目链接

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;int m,n;
int vis[100][100];
int f[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
string b,a[100];
int t,flag;
int xs,ys,xl,yl;
vector<pair<int,int> > q;bool judge(int x1,int y1){return (x1>=0&&x1<m&&y1>=0&&y1<n&&vis[x1][y1]==0&&a[x1][y1]!='X');
}
void dfs(int x,int y,int l){if(flag)return;if(x == xl&&y== yl){if(l==t){flag=1;}return ;}if(abs(x-xl)+abs(y-yl)+l>t || (t-l-abs(x-xl)-abs(y-yl))%2)return;for(int i=0;i<4;i++){int x1 = x+f[i][0];int y1 = y+f[i][1];if(judge(x1,y1)){vis[x1][y1]=1;dfs(x1,y1,l+1);vis[x1][y1]=0;}}}
int main()
{while(cin >> m >> n >> t){if(m==0)return 0;flag = 0;for(int i=0;i<m;i++){cin >> a[i];for(int j=0;j<n;j++){if(a[i][j]=='S'){xs=i;ys=j;}else if(a[i][j]=='D'){xl=i;yl=j;}}}memset(vis,0,sizeof vis);vis[xs][ys]=1;dfs(xs,ys,0);if(flag)cout << "YES" << endl;elsecout << "NO" << endl;}return 0;
}

5.别的应用

除了地图,我们还可以应用到别的方面
题目链接

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;int n,sum,l,flag=0;
int a[65];
int vis[65];void dfs(int m,int l2){  //个数,缺少长度if(flag)return;if(m==0 && l2==0){flag=1;}if(flag)return;if(l2==0)l2 = l;for(int i=0;i<n;i++){if(!vis[i] && a[i]<=l2){if(i>0){if(!vis[i-1]&&a[i]==a[i-1])continue;}vis[i]=1;dfs(m-1,l2-a[i]);vis[i]=0;if(a[i]==l2||l2==l)return;}}return;}
bool cmp(int a,int b)
{return a>b;
}
int main()
{while(cin >> n && n!=0){flag=0;sum=0;for(int i=0;i<n;++i){cin >> a[i];sum+=a[i];}sort(a,a+n,cmp);for(l=a[0];l<=sum/2;++l){if(sum%l)continue;memset(vis,0,sizeof(vis));dfs(n,l);if(flag){cout << l << endl;break;}}if(l>sum/2)cout << sum << endl;}return 0;
}

dfs就是刚,不撞三个墙不回头!
这里仅仅从算法的角度去观察,所以不要忘了别的基础理论a
天坑补完ヽ(°▽、°)ノ好耶!

C++算法——DFS(图解)相关推荐

  1. 二分图匹配匈牙利算法DFS实现

    1 /*==================================================*\ 2 | 二分图匹配(匈牙利算法DFS 实现) 3 | INIT: g[][]邻接矩阵; ...

  2. 排序算法 | 直接插入排序算法的图解、实现、复杂度和稳定性分析

    排序算法 | 直接插入排序算法的图解.实现.复杂度和稳定性分析 目录 1.直接插入排序定义 2.直接插入排序,步骤说明 3.动态图演示 4.代码实现,运行结果 5.算法分析 ① 时间复杂度分析 ② 空 ...

  3. 排序算法 | 直接选择排序,算法的图解、实现、复杂度和稳定性分析

    排序算法 | 直接选择排序,算法的图解.实现.复杂度和稳定性分析 目录 1.直接选择排序的原理 2.图解直接选择排序 3.算法代码实现 4.算法复杂度分析.稳定性分析 直接选择排序 1.直接选择排序的 ...

  4. (造轮子)C 创建队列和图实现广度优先算法(BFS)和深度优先算法(DFS)(数据结构)

    链表.队列和图实现BFS和DFS算法(C+造轮子+详细代码注释) 1.队列的链式存储结构   队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表.头指针指向队头节点,尾指针指向 ...

  5. 【排序算法】图解直接插入排序(图解堪比Debug显示每次循环结果)

    [排序算法]图解直接插入排序(图解堪比Debug分析每次循环结果) 写在前面: 本文主要介绍直接插入排序算法,通过图片一步步解释每一趟每一次的后移.代码通过C#实现,并输出每一次交换的情况和比较次数, ...

  6. Dijkstra算法证明图解

    目录 前言: 算法步骤 参数说明 算法描述 算法过程图解 算法可行性证明 一.数学归纳法: 假设前提: 归纳证明: 二.贪吃蛇法(个人理解): PTA题目: 前言: Dijkstra算法算是比较经典的 ...

  7. 深度优先搜索 python_黄哥Python:图深度优先算法(dfs)

    深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法.沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所在边都己被探寻过,搜索将回溯到发现 ...

  8. 分布式共识算法——Raft算法(图解)

    文章目录 Raft 算法 Raft 算法概念 Raft 角色 Raft 算法流程 Raft 算法原理 角色关系 任期原理 通信原理 图解算法流程 选举过程 执行操作过程(日志复制) 确保安全 Lead ...

  9. 算法动画图解:两数之和(哈希表)

    更多算法动画图解,长按此链接跳转AppStore 动画 算法动画图解:两数之和(哈希表) 思路 哈希表map用来保存一个数,另一个数在遍历nums的时候和map中的数尝试求和是否为target,如果求 ...

  10. 分布式共识算法——Paxos算法(图解)

    文章目录 Paxos Paxos概念 Paxos角色 Paxos算法流程 Paxos算法两个阶段 第一阶段:准备阶段 第二阶段:批准阶段 总结: 图解算法流程 举例说明算法流程 图解说明 一个简单的提 ...

最新文章

  1. Innodb与MySQL各自功能
  2. 有认知会推理!视觉大模型的未来不只靠表征
  3. 2018中国C++大会精彩回顾
  4. SpringCloud 入门教程(一): 服务注册
  5. 更换百度地图图标html,百度地图接口,自定义图标,点击切换图标
  6. 714. 买卖股票的zui佳时机含手续费(JavaScript)
  7. 08-10 性能瓶颈证据链
  8. 取消IE“已限制此网页运行可以访问计算机的脚本
  9. 多元回归模型与热力图绘制
  10. 无损连接性、保持函数依赖1
  11. web前端优化--图片优化
  12. Java部署斗鱼直播,iOS斗鱼直播项目
  13. html5中左浮动怎么写代码,html浮动详解(代码实例)
  14. Spring动态代理详解
  15. 当国际贸易撞上AI,会产生怎样的化学反应?
  16. Nginx 企业级优化
  17. python turtle后退_Turbot与python教程-实现后退
  18. web全栈工程师(前端进阶)学习线路图
  19. php查题,2020高校邦《PHP语言程序设计》答案在线查题
  20. julius开源语音识别引擎

热门文章

  1. 跨域的三种主流解决方案
  2. 各有短长:两款七月家庭有线组网方案推荐(转)
  3. PyQt5中的lambda表达式的使用
  4. 前后端交互ajax和axios入门讲解,以及http与服务器基础
  5. 【超分辨率】从SRCNN到EDSR,总结深度学习端到端超分辨率方法发展历程
  6. 修改bootstrap 中 CSS 样式表,以实现自己需要的部分样式。
  7. 车载毫米波雷达DOA估计综述
  8. 2004年7月15日
  9. 《深入理解计算机系统》读书笔记1
  10. 案例分析|爆款品牌完美日记的KOL投放策略