[学習アルゴリズム]実戦アルゴリズム10講-DFS


私がバーク金督がアップロードした「実戦アルゴリズム」のビデオを見て勉強した過程を記録します.
すべての写真は巴金督のブログから持ってきたものです.
https://blog.encrypted.gg/

アルゴリズムの説明


Depth First Search(DFS):各セルに多次元配列でアクセスする際の優先アクセス深度のアルゴリズム
DFSアルゴリズムでは、座標をスタックする必要があります.
  • 開始セルをスタックに入れ、アクセスタグ
  • を残します.
  • スタックから要素を取り出し、そのセルの上下左右に隣接するセルに対して
  • を3回行う.
  • 以前にセルにアクセスした場合は、何も行われません.セルに初めてアクセスした場合は、「アクセス済」というタグが残り、スタック
  • にセルが挿入されます.
  • スタックが空きになるまで2回繰り返します.
  • すべてのセルがスタックに1回入るので、時間の複雑さはO(N)
  • (N)です.
    pairは、2つの要素を組み合わせることができるSTLであり、予めサイズ関係が設定されている.
    自分で前の値を比較してから、後の値を比較します.
    DFSを実装する場合は、スタックに座標を配置する必要があります.pairを使用します.

    インプリメンテーション

    #include <bits/stdc++.h>
    using namespace std;
    #define X first
    #define Y second // pair에서 first, second를 줄여서 쓰기 위해서 사용
    int board[502][502] =
    {{1,1,1,0,1,0,0,0,0,0},
     {1,0,0,0,1,0,0,0,0,0},
     {1,1,1,0,1,0,0,0,0,0},
     {1,1,0,0,1,0,0,0,0,0},
     {0,1,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0},
     {0,0,0,0,0,0,0,0,0,0} }; // 1이 파란 칸, 0이 빨간 칸에 대응
    bool vis[502][502]; // 해당 칸을 방문했는지 여부를 저장
    int n = 7, m = 10; // n = 행의 수, m = 열의 수
    int dx[4] = {1,0,-1,0};
    int dy[4] = {0,1,0,-1}; // 상하좌우 네 방향을 의미
    int main(void){
      ios::sync_with_stdio(0);
      cin.tie(0);
      stack<pair<int,int> > S;
      vis[0][0] = 1; // (0, 0)을 방문했다고 명시
      S.push({0,0}); // 스택에 시작점인 (0, 0)을 삽입.
      while(!S.empty()){
        pair<int,int> cur = S.top(); S.pop();
        cout << '(' << cur.X << ", " << cur.Y << ") -> ";
        for(int dir = 0; dir < 4; dir++){ // 상하좌우 칸을 살펴볼 것이다.
          int nx = cur.X + dx[dir];
          int ny = cur.Y + dy[dir]; // nx, ny에 dir에서 정한 방향의 인접한 칸의 좌표가 들어감
          if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue; // 범위 밖일 경우 넘어감
          if(vis[nx][ny] || board[nx][ny] != 1) continue; // 이미 방문한 칸이거나 파란 칸이 아닐 경우
          vis[nx][ny] = 1; // (nx, ny)를 방문했다고 명시
          S.push({nx,ny});
        }
      }
    }

    BFS vs DFS



    BFSとDFSはアクセス順に大きな違いがある.BFSの隣接元素距離の現在の元素1の性質はDFSには適用されない.DFSには,一方向閉塞の前に,この性質のため距離を求める問題でDFSを使用できない直進的性質がある.
    Flood FillはBFS DFSを同時に使用できるが,距離測定はBFSのみを使用できる.
    したがって,多次元配列を巡回する問題はBFSで解決できる.
    DFSは図形や木の資料構造を学習する際に必要である.