深度优先搜索

数据结构7.3_图的遍历

佐手、 提交于 2020-02-03 04:37:39
我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次。 这一过程就叫做 图的遍历 。 图的遍历算法是求解 图的连通性问题 、 拓扑排序 和 求关键路径 等算法的基础。 然而,图的遍历要比树的遍历复杂得多。 因为图的任一顶点都可能和其余的顶点相邻接。 所以,在访问了某个顶点之后,可能沿着某条路径搜索之后,又回到该顶点上。 为了避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点。 为此,我们可以设一个辅助数组visited[0...n-1],它的初始值置为“假”或者零,一旦访问了顶点vi,便置visted[i]为“真”或者为被访问时的次序号。 通常有两条遍历图的路径:深度优先搜索和广度优先搜索。 它们对于无向图和有向图都适用。 =================================================== 深度优先搜索 (Depth First Search) DFS 这种遍历类似于树的先根遍历,是树的先根遍历的一种推广。 图(a) 是一张无向图 图(b)是深度优先搜索的过程 图(c)是广度优先搜索的过程 假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到; 若此图中尚有顶点未被访问

深度优先搜索(DFS)

◇◆丶佛笑我妖孽 提交于 2020-02-02 19:29:19
模板 int check(参数){ if(满足条件) return 1; return 0; } void DFS(int step){ 判断边界{ 相应操作 } 尝试每一种可能{ 满足check条件 标记 继续下一步 DFS(step + 1) 恢复初始状态(回溯的时候要用到) } } 来源: https://www.cnblogs.com/zjsaipplp/p/12253276.html

洛谷 深度优先搜索

自闭症网瘾萝莉.ら 提交于 2020-01-31 00:36:53
从某个状态开始,不断转移状态直到无法转移,在退回前一步,继续转移其他状态,如此不断重复得到解的过程即为深度优先搜索。采用 递归函数 实现较为简单 例题 部分和问题 给定n个正数,从中选出若干数,使其结果为一个固定值k,能输出yes,不能输出no # include <bits/stdc++.h> using namespace std ; int n ; int k ; int a [ 25 ] ; bool dfs ( int i , int sum ) { if ( i == n ) return sum == k ; if ( dfs ( i + 1 , sum ) ) return true ; if ( dfs ( i + 1 , sum + a [ i ] ) ) return true ; return false ; } int main ( ) { cin >> n ; for ( int i = 0 ; i < n ; i ++ ) cin >> a [ i ] ; cin >> k ; if ( dfs ( 0 , 0 ) ) printf ( "yes\n" ) ; else printf ( "no\n" ) ; return 0 ; } 来源: CSDN 作者: criminal king 链接: https://blog.csdn.net/qq

搜索与回溯算法(三)

≡放荡痞女 提交于 2020-01-28 05:00:19
本节学习要点: 1、 深度优先搜索的基本思想是什么? 2、 深度优选搜索的基本框架(用回溯递归实现) 3、 深度优先搜索算法要点 4、 搜索与回溯练习题二部分试题讲解。 搜索是人工智能中的一种基本方法,也是信息学竞赛选手所必须熟练掌握的一种方法,它最适合于设计基于一组生成规则集的问题求解任务,每个新的状态的生成均可使问题求解更接近于目标状态,搜索路径将由实际选用的生成规则的序列构成。我们在建立一个搜索算法的时候.首要的问题不外乎两个:以什么作为状态?这些状态之间又有什么样的关系?其实.在这样的思考过程中.我们已经不知不觉地将一个具体的问题抽象成了一个图论的模型——树(如图7-l所示)。 状态对应着顶点.状态之间的关系(或者说从一个状态到另一个状态的形成过程即生成规则)对应着边。这样的一棵树就叫做搜索树。初始状态对应着根结点,目标状态对应着目标结点。我们的任务就是找到一条从根结点到目标结点的路径——一个成功的解。搜索算法的实现类似于图或树的遍历,通常可以有两种不同的实现方法:深度优先搜索( DFS——Depth First Search )和宽度优先搜索( BFS——Breadth First Search ). 1 、深度优先搜索的基本思想: 如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索树。在深度优先搜索中,对于当前发现的结点

015查找有向图中的强连通分量

醉酒当歌 提交于 2020-01-26 22:52:02
查找有向图中的强连通分量 图学习笔记索引 本文参考《算法(第4版)》 1.实现代码 2.总结 图学习笔记索引 001自定义输入流In类实现 002背包数据类型Bag实现 003无向图数据类型实现 004基于图的深度优先搜索 005使用深度优先搜索找图中的所有连通分量 005-1基于深度优先搜索查找图中连通路径 006基于深度优先搜索判断图中是否存在环 007基于深度优先搜索判断一个无向图图是否是一个二分图 008广度优先搜索查找连通图中的最短路径 009有向图数据类型实现 010有向图的可达性 011带权重的无向边数据类型Edge实现 012加权无向图数据类型实现 013寻找有向环 014有向图中基于深度优先搜索的顶点排序 本文参考《算法(第4版)》 1.实现代码 点击文字获取:001自定义输入流In类实现 从文件中读取图的顶点关系。 tinyDG.txt中的内容: 13 22 4 2 2 3 3 2 6 0 0 1 2 0 11 12 12 9 9 10 9 11 8 9 10 12 11 4 4 3 3 5 7 8 8 7 5 4 0 5 6 4 6 9 7 6 Java代码: package algorithms.graph; import java.io.IOException; public class KosarajuSCC { private boolean

深度优先搜索DFS,求解部分和问题及poj2386水洼问题

别来无恙 提交于 2020-01-23 14:11:27
深度优先搜索(DFS)是搜索的手段之一。它从某个状态开始,不断地转移状态直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直至找到最终的解。 部分和问题: 给定整数a1、a2、...、an,判断是否可以从中选出若干数,使它们的和恰好为k。 分析: 从a1开始按顺序决定每个数加或不加,在全部n个数都决定后再判断它们的和是不是k即可。因为状态数是2 n+1 (每个数都有加和不加两种情况),所以复杂度是O(2 n )。 代码如下: /* 题目描述:能否找到数组a中的元素相加之和等于指定的数k 解决方法:深度优先搜索(dfs)对每个元素组合进行遍历 */ #include<iostream> using namespace std; int a[100],k,n; //已经从前i项得到了和sum,然后对于i项之后的进行分支 bool dfs(int i,int sum){ //如果前n项都计算过了,则返回sum是否与k相等 if(i==n) return sum == k; //不加上a[i]的情况 if(dfs(i+1,sum)) return true; //加上a[i]的情况 if(dfs(i+1,sum+a[i])) return true; //加不加a[i],都被无法与k相等,则返回false return false; } int main(){ cin

搜索

流过昼夜 提交于 2020-01-20 23:12:32
我这个Blog是补前边没写完的,所以肯定就不可能细讲了,那就直接上代码了 DFS(深度优先搜索) 代码: 1 void InitVisit() 2 { 3 // 初始化访问变量 4 for(int i=0;i<N;i++) 5 Visited[i] = false; 6 } 7 8 void DFS(int V) 9 { 10 // 深度优先搜索算法 11 Visited[V] = true; 12 printf("%d ",V); 13 for(int i=0;i<Nv;i++) 14 { 15 if(!Visited[i]&&G[V][i]) 16 DFS(i); 17 } 18 } 19 20 void ListComponentsWithDFS() 21 { 22 // 深度优先搜索格式输出 23 for(int i=0;i<Nv;i++) 24 { 25 if(!Visited[i]) 26 { 27 printf("{ "); 28 DFS(i); 29 printf("}\n"); 30 } 31 } 32 } BFS(广度优先搜索) ,代码: 1 void BFS(int V) 2 { 3 // 广度优先搜索,用队列辅助 4 const int MAX_SIZE = 100; 5 int Queue[MAX_SIZE]; 6 int first = -1,last

八数码问题

[亡魂溺海] 提交于 2020-01-20 04:24:29
八数码问题 八数码问题也叫九宫问题,是人工智能中状态搜索中的经典问题,其中,该问题描述为:在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。 这是一个典型的图搜索问题,但是该问题并不需要正在建立图数据结构来进行求解,而是将图的搜索方法抽象,运用到该问题上。以下是分析过程: 首先考虑将算法问题进行抽象和编码。如果把空格记成0,棋盘上的所有状态共有 9! = 362880种。我们要先找到一种方法把棋盘的状态进行编码。 容易想到的直观的状态表示方法,采用字符串方式编码,即把3*3的九宫格展平为一个长度为9的串,这样一个串即可代表一种当前整个数码盘的状态,例如:状态123456780表示如下: 1 2 3 4 5 6 7 8 0 进一步的,考虑转移(改变)状态,因为考虑只能由空格和一个数字进行对换,因此即可从数字0的位置开始考虑状态的转移,例如:上述的状态能够进行两种方向的转移,即为0和8进行对换,0和6进行对换,图示如下: 1 2 3 4 5 0 7 8 6 向上方式的转移 1 2 3 4 5 6 7 0 8 向左方向的转移 这样就可以从初始的状态扩展为一颗向目标状态的状态搜索树如下: 图片

深度优先搜索解决八数码难题

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-18 05:17:09
八数码问题 以前用java写的通过深度优先瘦素解决八数码难题。 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向。 具体实现思路: 每调用一次深度+1,如果深度达到指定深度,结束 找出0所在位置,对0的位置进行判断,判断是否能移动。判断顺序为左,上,右,下(列与行不能小于0,不能大于2)。为了避免出现先左移后右移等状况,需要设置一个变量,当变量为某个值时不能向某个方向移动。 判断能否向左移动,如果能,对0进行移动,将移动后的数组与最终数组进行判断,如果正确,则输出right,停止程序。如果不是则再次调用移动函数(递归调用)。 恢复原状态,写4个还原函数分别将数组还原到移动前的状态,将判断移动方向的变量还原到移动前的状态(回朔法)。 判断能否向其他方向移动(之后流程与向左移动相同)。 如果4个方向都判断完,结束 package aa ; import java . util . Scanner ; public class Az { static int [ ] [ ] arr2 = new int [ 3 ] [ 3 ] ; //= { { 1, 2, 3 }, { 8, 0, 4 }, { 7, 6, 5 } }; static int aaa ; //用于记录移动步数 static int

7. 深度优先搜索和广度优先搜索

て烟熏妆下的殇ゞ 提交于 2020-01-17 05:21:37
1. 实现和特性 定义 搜索-遍历 每个节点要访问且仅访问一次 对结点的访问顺序 深度优先(depth first search) 广度优先(breadth first search) 1.1 深度优先搜索 DFS代码(递归写法)及遍历顺序 非递归写法 def DFS ( self , tree ) : if tree . root is None : return [ ] visited , stack = [ ] , [ tree . root ] while stack : node = stack . pop ( ) visited . add ( node ) process ( node ) nodes = generate_related_nodes ( node ) stack . push ( nodes ) # other processing work . . . 1.2 广度优先搜索(breadth first search) 使用队列 BFS 使用队列实现 2. 算法题解 1) 102. 二叉树的层次遍历 广度优先遍历 递归:每层的结点返回到一个数组 迭代:维护一个队列,不同层时先将每层结点放入队列,之后遍历队列 并按入队顺序出队并赋给node,将node.val添加到当前数组 递归 // @lc code=start /** * Definition