图的深度优先搜索(DFS)
今天又复习了图的深度优先搜索,深深感觉了深搜就是外挂,岂止是外挂,简直就是外挂,动态规划做不出来的,深搜搜出来了,贪心贪不出来的深搜搜出来了,连并查集,拓扑排序做不出来的,深搜都做出来了,很遗憾以前深搜没有好好学。
深度优先搜索(Depth-First-Search)是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
深搜主要的是一个回溯的过程,标记当前的点已经用过,在用过的基础上,进行下一步,当进行到了最后发现此点不能用,于是就回溯回来,因此造成了该算法的时间复杂度为(O(n!));很容易造成超时,但是在部分题内,盲目搜索遍历一遍也挺挺快的,基本都是0ms,此算法,代码容易写,容易想,怪不得研究出dfs的两位神得了图灵奖,真6;
oj上边有很多适合练习深搜的题,如hdoj1045,还有最经典的n皇后问题,hdoj1258,南阳32组合数问题,南阳oj58最小步数问题,hdoj1016素数环问题,poj2362,zoj1003...(由于题目过多,只列取了经典的);
附几道深经典搜题及代码:
组合数问题:
描述
- 输入
- 输入n、r。
- 输出
-
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。 - 样例输入
-
5 3
- 样例输出
-
543 542 541 532 531 521 432 431 421 321
附代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,vis[1000],a[1000]={1000};
void dfs(int step)
{int i;if(step==n+1){for(i=1;i<n;i++)printf("%d",a[i]);printf("%d\n",a[i]); }for(i=m;i>=1;--i){if(!vis[i]&&i<a[step-1]){vis[i]=1;a[step]=i;dfs(step+1);vis[i]=0;}}
}
int main()
{while(scanf("%d%d",&m,&n),m+n){memset(vis,0,sizeof(vis));dfs(1);}return 0;
}
杭电1258:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[10100];
int res[10100]={10000};
int vis[10100],j,flag,n;
void dfs(int m,int cnt)
{int i;if(m==0){flag=1;for(j=1;j<cnt-1;j++)printf("%d+",res[j]);printf("%d\n",res[j]);return ;}for(i=1;i<=n;i++){if(!vis[i]&&m-a[i]>=0&&a[i]<=res[cnt-1]){vis[i]=1;res[cnt]=a[i];dfs(m-a[i],cnt+1);vis[i]=0;while(a[i]==a[i+1]&&i<=n)++i;}}
}
int main()
{int m,i,j;while(scanf("%d%d",&m,&n),(m||n)){for(i=1;i<=n;i++)scanf("%d",&a[i]);flag=0;printf("Sums of %d:\n",m);memset(vis,0,sizeof(vis));dfs(m,1);if(!flag)printf("NONE\n");}
}
杭电1016,素数环问题,约瑟夫环:
Note: the number of first circle should always be 1.
You are to write a program that completes above process.
Print a blank line after each case.
附代码 :
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int vis[30],a[30],m,n;
int is(int n)
{for(int i=2;i*i<=n;i++)if(n%i==0)return 0;return 1;
}
void dfs(int n,int c)
{if(c==n){if(is(a[n]+1)){printf("1");for(int i=2;i<=n;i++)printf(" %d",a[i]);printf("\n");}return ;}for(int i=2;i<=n;i++){if(!vis[i]&&is(a[c]+i)){a[c+1]=i;vis[i]=1;dfs(n,c+1);vis[i]=0;}}
}
int main()
{int flag=1;while(~scanf("%d",&n)){memset(vis,0,sizeof(vis));printf("Case %d:\n",flag++);vis[1]=1;a[1]=1;dfs(n,1);printf("\n");}return 0;
}
杭电2553,n皇后问题:
你的任务是,对于给定的N,求出有多少种合法的放置方法。
附代码:
#include<stdio.h>
#include<math.h>
int x[15];//x数组表示放在该列的哪个位置,下标表示列,值表示放置在第几行
int sum, n;
bool place (int v)
{ int i; for(i=1;i<v;++i) { if(x[i] == x[v] || abs(x[i]-x[v])==abs(i-v))//如果在同一行,或在对角线方向(为什么这里不判断是否为同一列呢?主要是因为x数组表示放在该列的哪个位置) return 0; } return 1;
}
void backtrack(int v)
{ int i; if(v>n) //把最后一个皇后放置成功后 sum++; else { for(i=1;i<=n;++i) //找n个皇后 { x[v]=i; if(place(v)) { backtrack(v+1); } } }
}
int main()
{ int ans[15]; for(n = 1; n <= 10; ++n) { sum = 0; backtrack(1); ans[n] = sum; } while(scanf("%d",&n), n) { printf("%d\n",ans[n]); } return 0;
}
图的深度优先搜索(DFS)相关推荐
- 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法
深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...
- 图的深度搜索c语言,求图的深度优先搜索!该怎么处理
当前位置:我的异常网» C语言 » 求图的深度优先搜索!该怎么处理 求图的深度优先搜索!该怎么处理 www.myexceptions.net 网友分享于:2013-03-16 浏览:12次 求图的 ...
- 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】
写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...
- 【数据结构】图的深度优先搜索
图的深度优先搜索类似于树的深度优先搜索.不同的是,图中可能包括循环,即我们有可能重复访问节点.为了避免访问已经访问过的节点,我们要使用一个布尔变量的数组. 例如,在下图中,我们从节点2开始访问.当访问 ...
- 深度优先搜索(DFS) 总结(算法+剪枝+优化总结)
深度优先搜索(DFS) 总结(算法+剪枝+优化总结) 本文中会引用部分实例.文献资料来自不同的作者之手,由于资料整理比较困难,转载地址不在文中列举.如有侵权请联系我更换或删除!对于提供题解思路的各位大 ...
- java数据结构和算法——图的深度优先(DFS)遍历
目录 一.图的遍历介绍 二.图的深度优先搜索(Depth First Search) 三.图的深度优先遍历算法步骤 四.图的深度优先遍历示例需求 五.图的深度优先遍历代码示例 一.图的遍历介绍 所谓图 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...
- 图的深度优先搜索-递归
图的深度优先搜索的过程: (1)从图的某个顶点V出发,访问V. (2)找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点.以该顶点为新顶点,重复此步骤,直到 刚顶点没有未bedi被访问的邻接点为止 ...
- 图的深度优先遍历DFS(JAVA)
图的深度优先遍历算法 在此介绍图的基本算法之一的深度优先遍历(DFS)算法 广度优先搜索(BFS). 什么是DFS 图是由节点(Node)和路径(Route)组成的一种数据结构,用于反应各节点间的关系 ...
最新文章
- 任何社区,只要能影响他人成长的人,都可以成为敏捷个人的荣誉会员
- 苹果ANCS协议学习【转】
- websocket采用tomcat方式,IOC类对象无法注入的解决方案
- GetWindowRect和GetClientRect(得到窗口坐标)
- php api 20121113,php添加gd
- Spring中的BeanPostProcessor接口
- 微服务实践分享(9)文档中心
- ConcurrentHashMap 1.8 源码分析
- js读取解析JSON类型数据【申明:来源于网络】
- IOS考试题3字体变大变小
- 面试中说这些话,到手的offer很容易飞
- 用python爬小说_5分钟带你用Python爬完《剑来》小说(附完整代码)!
- HeadFIrst Ruby 第二章总结 methods and classes
- word批量转换为pdf python脚本
- echar3D地图+3D柱形图
- Vue3+elementplus搭建通用管理系统实例六:后台主页搭建下
- 火狐浏览器打开IE窗口/IE跳谷歌页面等 --- 自定义协议---手动执行注册表
- libusb win32简介以及应用
- FastReport for Delphi2010 中文菜单显示不全或者乱码解决方法
- 【夯实Dubbo】Dubbo的核心特性
热门文章
- Excel进行粗糙的快速更换图片背景颜色
- 06_LR和最大熵模型_统计学习方法
- Linux服务-bind
- zookeeper源码 — 一、单机启动
- Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
- 【redis】在spring boot2.0中使用redis的StringRedisTemplate 自动注入@Autowired
- Linux_《Linux命令行与shell脚本编程大全》第十章学习总结
- HDU1799 循环多少次?
- 为什么PHP能够受到大家追捧和喜爱,又为什么饱受嘲讽?
- Bash漏洞引发僵尸网络狂欢