基础搜索dfs bfs

dfs

深度优先搜索是搜索的手段之一。他是从某个状态开始,不断地转移状态,直到无法转移,然后回退到前一步的状态,继续转移到其他状态,如此不断重复,直到找到最终的解。

深刻运用了递归的思想。隐式地利用了栈进行计算。

经典例题    POJ 2386

有一个大小为N×M的园子,雨后积起了水。八连通的积水被认为是连接在一起的。请求出园子里总共有多少水洼?

// 输入
int N, M;
char field[MAX_N][MAX_M + 1]; // 园子

// 现在位置(x,y)
void dfs(int x, int y) {
  // 将现在所在位置替换为.
  field[x][y] = '.';

  // 循环遍历移动的8个方向
  for (int dx = -1; dx <= 1; dx++) {
    for (int dy = -1; dy <= 1; dy++) {
      // 向x方向移动dx,向y方向移动dy,移动的结果为(nx,ny)
      int nx = x + dx, ny = y + dy;
     // 判断(nx,ny)是不是在园子内,以及是否有积水
      if (0 <= nx && nx < N && 0 <= ny && ny < M && field[nx][ny] == 'W') dfs(nx, ny);
    }
  }
  return ;
}

void solve() {
  int res = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      if (field[i][j] == 'W') {
        // 从有W的地方开始dfs
        dfs(i, j);
        res++;
      }
    }
  }
  printf("%d\n", res);
}

bfs

宽度优先搜索也是搜索的手段之一。他与深度优先搜索类似,从某个状态出发探索所有可以到达的状态。

与深度优先搜索不同之处在于搜索的顺序,宽度优先搜索总是先搜索距离初始状态近的状态。也就是说,它是按照开始状态—>只需一次就能到达的所有状态—>只需两次就能到达的所有状态—>……这样的顺序进行搜索。对于同一个状态,宽度优先搜索只经过一次,因此复杂度为O(状态数*转移的方式)。利用了队列。

经典例题     迷宫的最短路径

给定一个大小为N*M的迷宫,由通道('.')和墙壁('#')组成,其中通道S表示起点,通道G表示终点,每一步移动可以达到上下左右中不是墙壁的位置。试求出起点到终点的最小步数。(本题假定迷宫是有解的)(N,M<=100)

#include   
#include   
using namespace std;  
const int MAX_N = 100;  
const int MAX_M = 100;  
const int INF = 0x3f3f3f3f;  
typedef pair P;  
char maze[MAX_N][MAX_M + 1];  
int N, M;  
int sx, sy; //起点的位置  
int gx, gy; //终点的位置  
  
int d[MAX_N][MAX_M];//储存起点到某一点的距离  
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; //表明每次x和y方向的位移  
  
void bfs()  
{  
    queue

que; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) d[i][j] = INF; //初始化所有点的距离为INF que.push(P(sx, sy)); d[sx][sy] = 0; //从起点出发将距离设为0,并放入队列首端 while (que.size()) //题目保证有路到终点,所以不用担心死循环 { P p = que.front(); que.pop();//弹出队首元素 int i; for (i = 0; i < 4; i++) { int nx = p.first + dx[i]; int ny = p.second + dy[i];//移动后的坐标 //判断可移动且没到过 if (0 <= nx&&nx < N && 0 <= ny&&ny < M &&maze[nx][ny] != '#' &&d[nx][ny] == INF)//之前到过的话不用考虑,因为距离在队列中递增,肯定不会获得更好的解 { que.push(P(nx, ny)); //可以移动则设定距离为之前加一,放入队列 d[nx][ny] = d[p.first][p.second] + 1; if(nx==gx && ny==gy) break; } } if(i!=4) break; } } int main() { cin>>N>>M; for (int i = 0; i < N; i++) cin>>maze[i]; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) { if (maze[i][j] == 'S') { sx = i; sy = j; } if (maze[i][j] == 'G') { gx = i; gy = j; } } bfs(); cout<



你可能感兴趣的:(搜索)