일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- Backtracking
- 밑바닥부터 시작하는 딥러닝
- Machine Learning
- Linear Regression
- marchine learning
- 고전소설
- Python
- 밑바닥부터 시작하는 딥러닝2
- Baekjoon
- word2vec
- do it! 알고리즘 코딩테스트: c++편
- 딥러닝
- tree purning
- DFS
- slack variables
- classification
- dynamic programming
- Algorithm
- CBOW
- numpy
- boosting for classification
- RNN
- C++
- BFS
- Language model
- deep learning
- CPP
- SQLD
- boosting for regression
- jini impurity
Archives
- Today
- Total
newhaneul
[Do it! 알고리즘 코딩테스트: Chapter 5] 너비 우선 탐색(Breadth-First Search) 본문
728x90
본 포스팅은 Do it! 알고리즘 코딩테스트: C++편을 토대로 공부한 내용을 정리하기 위한 포스팅입니다.
https://github.com/KwonKiHyeok/Do_it_Alogrithm_Coding_Test_with_Cpp
GitHub - KwonKiHyeok/Do_it_Alogrithm_Coding_Test_with_Cpp: Do it! 알고리즘 코딩 테스트: C++편
Do it! 알고리즘 코딩 테스트: C++편. Contribute to KwonKiHyeok/Do_it_Alogrithm_Coding_Test_with_Cpp development by creating an account on GitHub.
github.com
너비 우선 탐색(Breadth-First Search)
너비 우선 탐색(Breadth-First Search, BFS)은 그래프나 트리와 같은 자료구조에서 루트 노드(또는 시작 노드)부터 시작하여 인접한 노드들을 먼저 방문한 후, 그 다음 레벨의 노드들을 방문하는 탐색 방법이다.
BFS의 핵심 아이디어
- 레벨별 탐색: 시작 노드에서부터 인접한 노드들을 모두 방문한 후, 그 다음 인접 노드들(한 단계 더 떨어진 노드)을 방문한다.
- 큐(Queue)를 사용: 탐색 순서를 유지하기 위해 선입선출(FIFO) 방식의 큐를 활용한다.
- 최단 경로 탐색: 가중치가 없는 그래프에서 시작 노드로부터 다른 노드까지의 최단 경로(최소 간선 수)를 찾는 데 유용하다.
BFS 알고리즘 단계
- 시작 노드 설정 및 초기화:
- 시작 노드를 큐에 넣고, 방문 표시(visited)를 한다.
- 반복 탐색:
- 큐가 비어 있지 않은 동안 다음을 반복한다:
- 큐의 맨 앞에 있는 노드를 꺼낸다.
- 해당 노드에 인접한 모든 노드를 확인한다.
- 방문하지 않은 노드라면 방문 표시를 하고 큐에 넣는다.
- 큐가 비어 있지 않은 동안 다음을 반복한다:
- 종료:
- 큐가 비면 모든 노드를 방문한 것으로 탐색을 종료한다.
// Baekjoon Online Judge Problem. 1260
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
void DFS(vector<vector<int>>& graph, vector<bool>& visited, int node);
void BFS(vector<vector<int>>& graph, vector<bool>& visited, int node);
int main() {
int N, M, V;
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M >> V;
vector<vector<int>> graph(N + 1);
vector<bool> visited1(N + 1, false);
for (int i = 0; i < M; i++) {
int a, b;
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
for (int i = 0; i < N + 1; i++)
sort(graph[i].begin(), graph[i].end());
DFS(graph, visited1, V);
cout << '\n';
vector<bool> visited2(N + 1, false);
BFS(graph, visited2, V);
return 0;
}
void DFS(vector<vector<int>>& graph, vector<bool>& visited, int node) {
cout << node << ' ';
visited[node] = true;
for (int i : graph[node]) {
if (visited[i] == false) {
DFS(graph, visited, i);
}
}
return;
}
void BFS(vector<vector<int>>& graph, vector<bool>& visited, int node) {
queue<int> q;
q.push(node);
while (q.empty() != true) {
int next = q.front();
visited[next] = true; q.pop();
cout << next << ' ';
for (int i : graph[next]) {
if (visited[i] == false) {
q.push(i);
visited[i] = true;
}
}
}
return;
}
// Baekjoon Online Judge Problem. 2178
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
void BFS(vector<vector<int>>& matrix, vector<vector<int>>& visited, pair<int, int> node);
int answer;
int main() {
int N, M;
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M;
vector<vector<int>> matrix(N, vector<int>(M, 0));
vector<vector<int>> visited(N, vector<int>(M, -1));
for (int i = 0; i < N; i++) {
string row;
cin >> row;
for (int j = 0; j < M; j++) {
matrix[i][j] = row[j] - '0';
}
}
BFS(matrix, visited, { 0, 0 });
cout << visited[N-1][M-1];
return 0;
}
void BFS(vector<vector<int>>& matrix, vector<vector<int>>& visited, pair<int, int> node) {
int y = node.first, x = node.second;
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };
queue<pair<int, int>> q;
q.push({ x, y });
visited[y][x] = 1;
while (!q.empty()) {
pair<int, int> cur = q.front(); q.pop();
for (int i = 0; i < 4; i++) {
int n_x = cur.first + dx[i];
int n_y = cur.second + dy[i];
if (-1 < n_y && n_y < visited.size() && -1 < n_x && n_x < visited[0].size()) {
if (visited[n_y][n_x] == -1 && matrix[n_y][n_x] == 1) {
visited[n_y][n_x] = visited[cur.second][cur.first] + 1;
q.push({ n_x, n_y });
}
}
else continue;
}
}
}
// Baekjoon Online Judge Problem. 1167
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
void BFS(vector<vector<pair<int, int>>>& tree, vector<bool>& visited, int node, vector<int>& length);
int answer;
int main() {
int V;
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> V;
vector<bool> visited(V + 1, false);
vector<int> length(V + 1, 0);
vector<vector<pair<int, int>>> tree(V + 1); // Change to vector of vector of pairs
for (int i = 1; i <= V; i++) {
int node;
cin >> node;
while (true) {
int a, b;
cin >> a;
if (a == -1) break;
cin >> b;
tree[node].push_back(pair<int, int>(a, b));
}
}
BFS(tree, visited, 1, length);
int maxi = -1, index = -1;
for (int i = 1; i <= V; i++) {
if (maxi < length[i]) {
maxi = length[i];
index = i;
}
}
visited = vector<bool>(V + 1, false);
length = vector<int>(V + 1, -1);
BFS(tree, visited, index, length);
maxi = -1;
for (int i = 1; i <= V; i++) {
if (maxi < length[i]) {
maxi = length[i];
}
}
cout << maxi;
return 0;
}
void BFS(vector<vector<pair<int, int>>>& tree, vector<bool>& visited, int node, vector<int>& length) {
visited[node] = true;
length[node] = 0;
queue<pair<int, int>> q;
q.push({ node, 0 });
while (!q.empty()) {
pair<int, int> cur = q.front(); q.pop();
visited[cur.first] = true;
for (pair<int, int> i : tree[cur.first]) {
if (visited[i.first] == false) {
length[i.first] = length[cur.first] + i.second;
q.push(i);
}
}
}
}
이 문제는 임의의 노드에서 가장 긴 경로로 연결된 노드는 트리의 지름에 해당하는 두 노드 중 하나라는 사실을 깨닫는 것이다. 따라서 아무 노드에서 한번 시작하여 트리의 지름에 해당하는 노드 하나를 찾고, 그 다음에 BFS를 한번 더 시행해 나머지 노드를 찾으면 해결할 수 있는 문제였다.
또 문제의 특이한 점은 queue에 pair<int, int> 형태를 넣는다는 점이 지금까지의 BFS 문제들과 달랐다.
728x90