핵심 요약
너비 우선 탐색
시작 노드에 인접한 노드들부터 차근차근 탐색하는 알고리즘
간선의 비용이 동일한 최단거리 문제에서 활용된다.
구현 방식
1. 큐를 사용한다
큐에 노드를 push하고, 방문 처리한다.
노드를 큐에서 pop하고, 인접 노드를 모두 push한 뒤 방문 처리한다.
2. while문의 조건을 통해 모든 노드를 탐색할 때까지 돌린다.
3. while문 안에 for문을 넣어 인접 노드를 탐색한다.
1. 입력이 배열로 주어질 때
배열에 입력값들을 넣은 뒤, 이동해야 하는 방향(주로 상하좌우)을 탐색한다.
이때, 이동 방향은 dx[4] = {-1, 1, 0, 0} 과 dy[4] = {0, 0, 1, -1}을 이용하여 처리하는 편이다.
이 경우 방문 정보는 bool 형의 2차원 배열로 처리한다.
for 반복문에서 이동의 가짓수만큼 반복한다.
아래는 백준 1012 유기농 배추 문제로 배열이 입력으로 주어지는 BFS 문제이다.
#include <iostream>
#include <queue>
#include <algorithm>
#include <memory.h>
using namespace std;
struct Pos{
int x;
int y;
};
bool visited[55][55];
char map[55][55];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int col, row, k;
void bfs(int startX, int startY){
queue<Pos> q;
q.push({startX, startY});
visited[startY][startX] = true;
while(!q.empty()){
int x = q.front().x;
int y = q.front().y;
q.pop();
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 0 && nx < col && ny >= 0 && ny < row){
if(map[ny][nx] == '1' && visited[ny][nx] == false){
q.push({nx, ny});
visited[ny][nx] = true;
}
}
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--){
memset(map, '0', sizeof(map));
memset(visited, false, sizeof(visited));
cin>>col>>row>>k;
for(int i = 0; i < k; i++){
int x, y;
cin>>x>>y;
map[y][x] = '1';
}
int cnt = 0;
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
if(map[i][j] == '1' && visited[i][j] == false){
bfs(j, i);
cnt++;
}
}
}
cout<<cnt<<"\n";
}
return 0;
}
2. 입력이 정점과 간선으로 주어질 때
벡터 배열을 이용하여 인접리스트를 구현한다.
vector<int> v[크기]; 와 같이 구성된다.
이 경우 방문 정보는 bool 형의 1차원 배열로 처리한다.
for 반복문에서 v[]의 크기만큼 반복한다.
아래는 백준 2606 바이러스 문제로 입력이 정점과 간선으로 주어지는 BFS 문제의 답안이다.
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
vector <int> map[1003];
bool visited[1003];
int bfs(int start){
int cnt = 0;
queue<int> q;
q.push(start);
visited[start] = true;
while(!q.empty()){
int cur = q.front();
q.pop();
for(int i = 0; i < map[cur].size(); i++){
if(visited[map[cur][i]] == false){
visited[map[cur][i]] = true;
q.push(map[cur][i]);
cnt++;
}
}
}
return cnt;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin>>n;
cin>>m;
for(int i = 0; i < m; i++){
int u, v;
cin>>u>>v;
map[u].push_back(v);
map[v].push_back(u);
}
cout<<bfs(1);
return 0;
}
구현 방법
'알고리즘을 위한 간략 정리 > 그래프 탐색' 카테고리의 다른 글
[C++] 벨만-포드 알고리즘 (0) | 2023.10.08 |
---|---|
[C++] 유니온 파인드(Union-Find) (0) | 2023.10.03 |
[C++] DFS(Depth-First Search) (0) | 2023.10.03 |
백트래킹(Back-Tracking) (0) | 2023.10.03 |