深搜与广搜

深搜
深度搜索的过程  深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。在深度优先搜索中,对于最新发现的节点,如果它还有以此为起点而未搜索的边,就沿此边继续搜索下去。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v有那条边的始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被发现为止。即  
⒈以给定的某个顶点V0为起始点,访问该顶点;    
⒉选取一个与顶点V0相邻接且未被访问过的顶点V1,用V1作为新的起始点,重复上述   过程;    
⒊当到达一个其所有邻接的顶点都已被访问过的顶点Vi时,就退回到新近被访问过的   顶点Vi- 1,继续访问Vi-1尚未访问的邻接点,重复上述搜索过程;    
⒋直到从任意一个已访问过的顶点出发,再也找不到未被访问过的顶点为止,遍历便  告完成。    
这种搜索的次序体现了向纵深发展的趋势,所以称之为深度优先搜索


我们从这幅图中阐述一下深搜的含义:从a点开始,到C-E-G,如果没有找到想要的结果就从G返回到E判断E是否还有其他的子节点,也就是F,如果F也不满足需求那就回到C以此类推。

例题理解:
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid. 
Input
The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket. 
Output
For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets. 
Sample Input
1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5 
****@
*@@*@
*@**@
@@@*@
@@**@
0 0 
Sample Output
0
1
2
2

意思就是一块油田,@代表有油,*代表没油。让你找出有多少个不挨着的油田,就好比Sample input里面第二组数据来讲,里面所有的@都是挨着的,因此输出是1。
根据下面的代码理解一下深搜


AC深搜代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e2 + 10;
typedef long long LL;//就是将longlong型在下文中可以简写为LL,不用再那么麻烦了//
char s[MAX][MAX];
int n,m,vis[MAX][MAX],ans;//vis[][]的作用就是标记值为@的地方让该点坐标对应的vis值为1// 
int fx[8] = {0,0,-1,1,-1,1,-1,1}; 
int fy[8] = {-1,1,0,0,-1,-1,1,1}; // 8 个方向 // 
void dfs(int x,int y)//利用递归求出各个方向的@//
{
    vis[x][y] = 1;
    for(int i = 0; i < 8; i++){
        int xx = x + fx[i],yy  = fy[i] + y;
        if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@') // 判断是否出界, 是否已经搜索过, 是否为油田 
            dfs(xx,yy);
    }
}
int main()
{
	
    while(~scanf("%d %d",&n,&m),m){
        memset(vis,0,sizeof(vis));//将数组vis中所有的元素初始化为0//
        for(int i = 0; i < n; i++)
            scanf("%s",s[i]);//输入第一行数据// 
        ans = 0;//要输出的结果// 
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                if(!vis[i][j] && s[i][j] == '@')//如果输入是@且没有被搜到过相连接//
                    {	
						ans++; 
						dfs(i,j);// 第一次搜到 + 1 //
					} 
        printf("%d\n",ans);
    }
    return 0;
}
广搜


广度优先搜索是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径 算法和Prim最小生成树 算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

还是根据上面那个图来说广搜的含义:从A点出发,判断A点所有的节点是否满足条件,如果不满住就往下一个节点进行。也就是说广搜是一个等级一个等级的搜,而深搜是一直往下在一个个返回。

也是上面这个例题,AC广搜代码如下:

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 1e2 + 10;
typedef long long LL;
char s[MAX][MAX];
int n,m,vis[MAX][MAX],ans;
int fx[8] = {0,0,-1,1,-1,1,-1,1},fy[8] = {-1,1,0,0,-1,-1,1,1};
struct node{
    int x,y;
};//坐标 //
void bfs(int x,int y){
    vis[x][y] = 1;
    queue <node> q;//定义一个带有坐标xy的队列q//
    node o;
    o.x = x;
	o.y = y;
    q.push(o);//将第一个@的坐标放入队列// 
    while(!q.empty())//判断队列非空// 
	{
        o = q.front();//将第一个值给o// 
        q.pop();//将第一个数据删除方便下一次储存// 
        for(int i = 0; i < 8; i++)
		{ // 8 个方向  
            int xx = o.x + fx[i],yy = o.y + fy[i];
            if(xx >= 0 && yy >= 0 && xx < n && yy < m && !vis[xx][yy] && s[xx][yy] == '@')
			{  // 判断是否出界, 是否已经搜索过, 是否为油田 
                node w;
                vis[xx][yy] = 1;//将找到的地方标记为1// 
                w.x = xx; 
				w.y = yy;
                q.push(w);//将该点放入队列中// 
            }
        }
    }
}
int main()
{
    while(~scanf("%d %d",&n,&m),m)
	{
        memset(vis,0,sizeof(vis));
        for(int i = 0; i < n; i++)
            scanf("%s",s[i]);
        ans = 0;
        for(int i = 0; i < n; i++)
           { for(int j = 0; j < m; j++)
                if(!vis[i][j] && s[i][j] == '@')
                {
                   	ans++; 
					bfs(i,j); //将所有与第一个@相连的@全部标记成1,再进行下一次循环 // 第一次搜到 + 1  
				}
			} 
        printf("%d\n",ans);
    }
    return 0;
}

搜索练习

愿你一生清澈明朗,做你愿做之事,爱你愿爱之人!




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值