今天又复习了图的深度优先搜索,深深感觉了深搜就是外挂,岂止是外挂,简直就是外挂,动态规划做不出来的,深搜搜出来了,贪心贪不出来的深搜搜出来了,连并查集,拓扑排序做不出来的,深搜都做出来了,很遗憾以前深搜没有好好学。

深度优先搜索(Depth-First-Search)是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

事实上,深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.

深搜主要的是一个回溯的过程,标记当前的点已经用过,在用过的基础上,进行下一步,当进行到了最后发现此点不能用,于是就回溯回来,因此造成了该算法的时间复杂度为(O(n!));很容易造成超时,但是在部分题内,盲目搜索遍历一遍也挺挺快的,基本都是0ms,此算法,代码容易写,容易想,怪不得研究出dfs的两位神得了图灵奖,真6;

oj上边有很多适合练习深搜的题,如hdoj1045,还有最经典的n皇后问题,hdoj1258,南阳32组合数问题,南阳oj58最小步数问题,hdoj1016素数环问题,poj2362,zoj1003...(由于题目过多,只列取了经典的);

附几道深经典搜题及代码:

组合数问题:

描述

找出从自然数1、2、... 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。

输入
输入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:

Problem Description
Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t=4, n=6, and the list is [4,3,2,2,1,1], then there are four different sums that equal 4: 4,3+1,2+2, and 2+1+1.(A number can be used within a sum as many times as it appears in the list, and a single number counts as a sum.) Your job is to solve this problem in general.
Input
The input will contain one or more test cases, one per line. Each test case contains t, the total, followed by n, the number of integers in the list, followed by n integers x1,...,xn. If n=0 it signals the end of the input; otherwise, t will be a positive integer less than 1000, n will be an integer between 1 and 12(inclusive), and x1,...,xn will be positive integers less than 100. All numbers will be separated by exactly one space. The numbers in each list appear in nonincreasing order, and there may be repetitions.
Output
For each test case, first output a line containing 'Sums of', the total, and a colon. Then output each sum, one per line; if there are no sums, output the line 'NONE'. The numbers within each sum must appear in nonincreasing order. A number may be repeated in the sum as many times as it was repeated in the original list. The sums themselves must be sorted in decreasing order based on the numbers appearing in the sum. In other words, the sums must be sorted by their first number; sums with the same first number must be sorted by their second number; sums with the same first two numbers must be sorted by their third number; and so on. Within each test case, all sums must be distince; the same sum connot appear twice.
Sample Input
4 6 4 3 2 2 1 1 5 3 2 1 1 400 12 50 50 50 50 50 50 25 25 25 25 25 25 0 0
Sample Output
Sums of 4: 4 3+1 2+2 2+1+1 Sums of 5: NONE Sums of 400: 50+50+50+50+50+50+25+25+25+25 50+50+50+50+50+25+25+25+25+25+25
#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,素数环问题,约瑟夫环:

Problem Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.

Note: the number of first circle should always be 1.

Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.

You are to write a program that completes above process.

Print a blank line after each case.

Sample Input
6 8
Sample Output
Case 1: 1 4 3 2 5 6 1 6 5 2 3 4Case 2: 1 2 3 8 5 6 7 4 1 2 5 8 3 4 7 6 1 4 7 6 5 8 3 2 1 6 7 4 3 8 5 2

附代码 :

#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皇后问题:

Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10

附代码:

#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)相关推荐

  1. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  2. 图的深度搜索c语言,求图的深度优先搜索!该怎么处理

    当前位置:我的异常网» C语言 » 求图的深度优先搜索!该怎么处理 求图的深度优先搜索!该怎么处理 www.myexceptions.net  网友分享于:2013-03-16  浏览:12次 求图的 ...

  3. 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  4. 【数据结构】图的深度优先搜索

    图的深度优先搜索类似于树的深度优先搜索.不同的是,图中可能包括循环,即我们有可能重复访问节点.为了避免访问已经访问过的节点,我们要使用一个布尔变量的数组. 例如,在下图中,我们从节点2开始访问.当访问 ...

  5. 深度优先搜索(DFS) 总结(算法+剪枝+优化总结)

    深度优先搜索(DFS) 总结(算法+剪枝+优化总结) 本文中会引用部分实例.文献资料来自不同的作者之手,由于资料整理比较困难,转载地址不在文中列举.如有侵权请联系我更换或删除!对于提供题解思路的各位大 ...

  6. java数据结构和算法——图的深度优先(DFS)遍历

    目录 一.图的遍历介绍 二.图的深度优先搜索(Depth First Search) 三.图的深度优先遍历算法步骤 四.图的深度优先遍历示例需求 五.图的深度优先遍历代码示例 一.图的遍历介绍 所谓图 ...

  7. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...

  8. 图的深度优先搜索-递归

    图的深度优先搜索的过程: (1)从图的某个顶点V出发,访问V. (2)找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点.以该顶点为新顶点,重复此步骤,直到 刚顶点没有未bedi被访问的邻接点为止 ...

  9. 图的深度优先遍历DFS(JAVA)

    图的深度优先遍历算法 在此介绍图的基本算法之一的深度优先遍历(DFS)算法 广度优先搜索(BFS). 什么是DFS 图是由节点(Node)和路径(Route)组成的一种数据结构,用于反应各节点间的关系 ...

最新文章

  1. 任何社区,只要能影响他人成长的人,都可以成为敏捷个人的荣誉会员
  2. 苹果ANCS协议学习【转】
  3. websocket采用tomcat方式,IOC类对象无法注入的解决方案
  4. GetWindowRect和GetClientRect(得到窗口坐标)
  5. php api 20121113,php添加gd
  6. Spring中的BeanPostProcessor接口
  7. 微服务实践分享(9)文档中心
  8. ConcurrentHashMap 1.8 源码分析
  9. js读取解析JSON类型数据【申明:来源于网络】
  10. IOS考试题3字体变大变小
  11. 面试中说这些话,到手的offer很容易飞
  12. 用python爬小说_5分钟带你用Python爬完《剑来》小说(附完整代码)!
  13. HeadFIrst Ruby 第二章总结 methods and classes
  14. word批量转换为pdf python脚本
  15. echar3D地图+3D柱形图
  16. Vue3+elementplus搭建通用管理系统实例六:后台主页搭建下
  17. 火狐浏览器打开IE窗口/IE跳谷歌页面等 --- 自定义协议---手动执行注册表
  18. libusb win32简介以及应用
  19. FastReport for Delphi2010 中文菜单显示不全或者乱码解决方法
  20. 【夯实Dubbo】Dubbo的核心特性

热门文章

  1. Excel进行粗糙的快速更换图片背景颜色
  2. 06_LR和最大熵模型_统计学习方法
  3. Linux服务-bind
  4. zookeeper源码 — 一、单机启动
  5. Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
  6. 【redis】在spring boot2.0中使用redis的StringRedisTemplate 自动注入@Autowired
  7. Linux_《Linux命令行与shell脚本编程大全》第十章学习总结
  8. HDU1799 循环多少次?
  9. 为什么PHP能够受到大家追捧和喜爱,又为什么饱受嘲讽?
  10. Bash漏洞引发僵尸网络狂欢