시작하는 칸을 큐에 넣고 방문했다는 표시를 남김
큐에서 원소를 꺼내어 그 칸에 상하좌우로 인접한 칸에 대해 3번을 진행
해당 칸을 처음 방문한다면 방문했다는 표시를 남기고 해당 칸을 큐에 삽입 / 이전에 방문했다면 아무것도 하지않음
큐가 빌 때까지 2번을 반복
방문 표시를 남기므로 모든 칸은 큐에 1번씩만 들어간다.
따라서 시간복잡도는 칸이 N개일 때 O(N)이 된다.
만약 행이 R개이고, 열이 C개이면 O(RC) 가 된다.
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
// 판. 1이면 데이터 있는 칸, 0이면 데이터가 없는 칸
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}
};
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);
queue<pair<int,int>> Q;
// BFS 탐색을 시작하는 칸을 (0,0)으로 잡았다.
vis[0][0] = 1;
Q.push({0,0});
while(!Q.empty())
{
// 큐에 저장된 칸(좌표)을 꺼내와서 cur에 저장
pair<int,int> cur = Q.front();
Q.pop();
cout << '(' << cur.X << ", " << cur.Y << ") -> ";
// 처리할 칸(cur)의 상하좌우 칸에 대해 처리
for(int i = 0; i < 4; i++){
int nx = cur.X + dx[i]; // 상하좌우 칸에 대한 좌표 데이터 저장
int ny = cur.Y + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= m)
continue;
if(vis[nx][ny] || board[nx][ny] != 1)
continue;
vis[nx][ny] = 1; // 방문 처리하고 상하좌우 칸을 큐에 push
Q.push({nx,ny});
}
}
}
시작점에 방문했다는 표시를 남기지 않는 경우
큐에 넣을 때 방문했다는 표시를 하는 대신 큐에서 빼낼 때 방문했다는 표시를 남기는 경우