本专题主要锻炼搜索的两大方法——bfs (宽度优先搜索)和 dfs (深度优先搜索)

===================================华丽的分割线=======================================

一、bfs——宽度优先搜索(Breadth First Search)    

  bfs主要运用于搜索中求最短时间的问题,搜索过程中一般需要运用 queue 的操作。

  bfs的核心思想是:从初始结点开始,应用算符生成第一层结点,检查目标结点是否在这些后继结点中,若没有,再用产生式规则将所有第一层的结点逐一扩展,得到第二层结点,并逐一检查第二层结点中是否包含目标结点。若没有,再用算符逐一扩展第二层所有结点……,如此依次扩展,直到发现目标结点为止。

具体的操作如下:

       1.首先需要将 队列 和 visit数组 清空。(这一点很重要!!!)

       2.然后将起点信息 push 进队列,标记为visited(修改 visit 数组中元素对应的值),信息一般都用结构体存储,当然,所建立的 queue 也必须是结构体类型的。

       3.接下来就是主体了——一个while循环,判断条件为 队列非空。

   每次循环,需要取出队首元素,然后 pop 出队首元素。首先判断是否已满足题目要求,满足的话 return 所需要的信息,否则以该元素为中心,遍历四周的节点,如果节点可以到达且未被访问,则将该节点的信息 push 进队列,并标记为visited。重复循环即可。

  4.如果到达while循环外面,说明题目的要求无法达到,返回 impossible 即可。

 

伪代码如下:(凯神提供!!!快去仰慕)

Q empty
init state - s
Q push s
visite s
while(Q ! empty)
{
  state now = Q front
  Q pop
  next = update now
  if(next not visited)
  {
    Q push next
    visite next
  }  
}
return impossible

 

几个注意点:

       1.各个数据的清空和初始化

  2.遍历四周的节点可以用一个for循环,具体实现方法请看最后的题解。

 

===============================华丽的分割线的大儿子=================================

 

二、dfs——深度优先检索(Depth First Search)

  dfs主要运用于求解满足题目的所有可能的解法的数目,显然这种问题无法用 bfs 解决,因为 bfs 只能求解最优解,而用 dfs 就可以了。 

       dfs所遵循的搜索策略是尽可能“深”地搜索图。在深度优先搜索中,对于最新发现的结点,如果它还有以此为起点而未搜过的边,就沿着边继续搜索下去。当结点v的所有边都已被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个过程反复进行直到所有结点都被发现为止。

  深度优先搜索遍历类似于树的先序遍历。假定给定图G的初态是所有顶点均未被访问过,在G中任选一个顶点i作为遍历的初始点,则深度优先搜索递归调用包含以下操作:

  (1)访问搜索到的未被访问的邻接点;

  (2)将此顶点的visited数组元素值置1;

  (3)搜索该顶点的未被访问的邻接点,若该邻接点存在,则从此邻接点开始进行同样的访问和搜索。

dfs可描述为:

  (1)访问v0顶点;

  (2)置 visited[v0]=1;

  (3)搜索v0未被访问的邻接点w,若存在邻接点w,则dfs(w)。

遍历过程:     

   dfs 在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点w1;再从 w1 出发,访问与 w1邻 接但还没有访问过的顶点 w2;然后再从 w2 出发,进行类似的访问,… 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。

  接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。

深度优先搜索基本算法如下{递归算法}

PROCEDURE dfs_try(i);
  FOR i:=1 to maxr DO
    BEGIN
      IF 子结点 mr 符合条件  THEN
          BEGIN
            产生的子结点mr入栈;
            IF 子结点mr是目标结点 
               THEN 输出
               ELSE dfs_try(i+1);
            栈顶元素出栈;
          END;
    END; 

 

==============================华丽的分割线的小儿子==================================

  题目链接:https://vjudge.net/contest/65959 

                                                           简单搜索专题题解                                

A.       POJ 1321       棋盘问题

题目要求求出可行解的数目,显然要用dfs,代码如下:

 1 #include<iostream>
 2 #include<cstring>
 3 
 4 using namespace std;
 5 
 6 char a[8][8];
 7 int num,n,k;
 8 
 9 struct node
10 {
11     int c[8];
12     int count;
13 };
14 
15 void dfs(int x,struct node map)
16 {
17     if(x>=n)
18         return;
19     /*if(map.count==k)
20     {
21         num++;
22         return;
23     }*/
24     for(int i=0;i<n;i++)
25     {
26         if(a[x][i]=='.')
27             continue;
28     
29         if(map.c[i]==0)
30         {
31             struct node map1;
32         //    memcpy(map1.b,map.b,sizeof(map.b));
33             memcpy(map1.c,map.c,sizeof(map.c));
34             map1.count=map.count;
35         
36             map1.count++;
37             map1.c[i]=1;
38             if(map1.count==k)
39             {
40                 num++;
41             //    dfs(x+1,map);
42             //    cout<<num<<endl;
43                 continue;
44             }
45             else
46             {
47                 dfs(x+1,map1);
48             }
49         }
50     }    
51     dfs(x+1,map);
52 }
53 
54 int main()
55 {    
56     while(cin>>n>>k)
57     {
58         if(n==-1&&k==-1)
59             break;
60            for(int i=0;i<n;i++)
61         {
62             for(int j=0;j<n;j++)
63                 cin>>a[i][j];
64         }
65         num=0;
66         struct node map;
67     //    memset(map.b,0,sizeof(map.b));
68         memset(map.c,0,sizeof(map.c));
69         map.count=0;
70         //cout<<num<<endl;
71         dfs(0,map);
72         cout<<num<<endl;
73     }     
74     return 0;
75 }
View Code

相关文章:

  • 2022-12-23
  • 2021-07-11
  • 2022-12-23
  • 2021-09-01
  • 2022-01-01
  • 2021-06-25
  • 2021-12-16
猜你喜欢
  • 2021-10-19
  • 2022-03-10
  • 2021-08-09
  • 2022-12-23
  • 2022-12-23
  • 2021-10-15
  • 2021-09-09
相关资源
相似解决方案