
๋ค์ด๊ฐ๋ฉฐ
์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ์ค ์ต๋จ ๊ฒฝ๋ก ํ์์ด๋ผ๋์ง, ๋ ธ๋๋ฅผ ๊ตฌ์ฑํด์ ํ์ํด์ผํ๋ ๋ฌธ์ ๋ค์ด ๊ฝค๋ ์์ต๋๋ค. ๋ํ์ ์ธ ํ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก๋ Binary Search, ๊น์ด์ฐ์ ํ์(DFS, Depth First Search), ๋๋น์ฐ์ ํ์(BFS, Breadth First Search) ๋ฑ์ด ์์ต๋๋ค. ํนํ ๋ง์ด ํท๊ฐ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ DFS๋ฅผ ์ฌ์ฉํด์ผ ํ๋๊ฐ BFS๋ฅผ ์ฌ์ฉํด์ผํ๋๊ฐ ์ ๋๋ค. ์ค๋์ BFS ์์ฃผ๋ก ์ค๋ช ์ ๋๋ฆด ์์ ์ธ๋ฐ, ๋ํ์ ์ผ๋ก ์ต๋จ ๊ฒฝ๋ก ํ์, ์ต์ ํ์ ํ์, ๋ฐฉ๋ฌธ ๊ฐ๋ฅํ ๋ชจ๋ ๋ ธ๋ ํ์ ๋ฑ ์ด์ ์ํ๋ฅผ ๊ธฐ์ตํ์ง ์์ ์ํ๋ก ํน์ ๊ฒฝ๋ก๋ฅผ ํ์ํ ๋ BFS๋ฅผ ์ฌ์ฉํฉ๋๋ค. BFS๋ ํ์ ๊น์ด๋ฅผ ์์ฐ์ค๋ฝ๊ฒ ์นด์ดํ ๊ฐ๋ฅํ ์ฅ์ ์ด ์์ต๋๋ค.

ํน์ง
| ๊ตฌ๋ถ | BFS | DFS |
| ํ์ ๋ฐฉ์ | ๊ฐ๊น์ด ๋ ธ๋๋ถํฐ ํ์ | ํ ๊ฒฝ๋ก๋ฅผ ๋๊น์ง ํ์ |
| ์๋ฃ๊ตฌ์กฐ | ํ(Queue) | ์คํ(Stack) ๋๋ ์ฌ๊ท |
| ์ต๋จ ๊ฒฝ๋ก | O (๊ฐ์ค์น ๋์ผ ์) | X |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ | ํผ (ํ์ ๋ง์ ๋ ธ๋ ๋ณด๊ด) | ์ ์ (๊ฒฝ๋ก ๊ธฐ๋ฐ ํ์) |
| ์ ํฉํ ๋ฌธ์ ์ ํ | ์ต๋จ ๊ฑฐ๋ฆฌ, ์ต์ ํ์ | ๋ชจ๋ ๊ฒฝ์ฐ ํ์, ๊ฒฝ๋ก ์ถ์ |
๊ธฐ๋ณธ์ ์ธ BFS์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. queue๋ฅผ ์ฌ์ฉํ๋ฉฐ ์์ ๋ ธ๋๋ฅผ ์ฝ์ ํ ์ธ์ ํ ๋ ธ๋๋ค์ ์์ฐจ๋ก ์ํํ๋ฉด์ queue์ pushํฉ๋๋ค. ํ ์ฐจ๋ก(๋ ๋ฒจ)๊ฐ ๋๋๋ฉด queue์์ ๋ ธ๋๋ฅผ popํ๊ฒ ๋๋ฉด ์ธ์ ํ ๋ ธ๋๋ค๋ถํฐ ์ํํ๊ฒ ๋ฉ๋๋ค.
# python
def bfs(graph:Dict, start:int): # Dict ์๋ฃํ ํํ๋ก ์ค๋ค. key๋ ๋
ธ๋, value๋ ์ธ์ ๋
ธ๋๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
visited = {i:False for i in graph.keys()} # ๋ฐฉ๋ฌธ ๋ฐฐ์ด. visited[node] = True์ด๋ฉด node๋ ๋ฐฉ๋ฌธ์ด ๋๋ ์ํ์ด๋ค.
queue = [start]
visited[start] = True
while queue: # ํ๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณต
current = queue.pop(0) #queue์์ ๋
ธ๋๋ฅผ ํ๋ ๋นผ ์จ๋ค. ์ด ๋
ธ๋๋ฅผ current๋ผ๊ณ ํ์.
for nxt in graph[current]: # current์ ์ธ์ ๋
ธ๋๋ค์ ํ์ธํ๋ค. ์ด ๊ฐ๊ฐ์ ๋
ธ๋๋ฅผ nxt๋ผ๊ณ ํ์.
if not visited[nxt]: # ๋ง์ผ nxt์ ๋ฐฉ๋ฌธํ์ง ์์๋ค๋ฉด
#nxt ๋ฐฉ๋ฌธ
queue.append(nxt)
visited[nxt] = True
๋ฌธ์ ํ์ด
๋ฐฑ์ค 1260
๋จผ์ ๊ฐ๋จํ BFS ํ์ด ๋ฌธ์ ๋ฅผ ๋ณด๊ฒ ์ต๋๋ค. ๋ฐฑ์ค 1260๋ฌธ์ ์ ๋๋ค(๋งํฌ).

ํ์ด ๊ณผ์ ์ ์ ๋ ฅ๋ฐ์ ์ ์ ๊ณผ ๊ฐ์ ์ ํตํด ๊ทธ๋ํ๋ฅผ ๊ตฌ์ฑํ๊ณ ์์ ์ดํด๋ดค๋ bfsํจ์๋ฅผ ์คํํ๋ฉด ๋ฉ๋๋ค.
// ๋ฐฑ์ค 1260: DFS์ BFS
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
vector<vector<int>> relations;
vector<bool> visited;
queue<int> q;
int N, M;
void dfs(int key)
{
printf("%d ", key+1);
if (!visited[key])
visited[key] = true;
else
return;
for (const auto r : relations[key])
{
if (!visited[r])
dfs(r);
}
}
void bfs(int start)
{
q.push(start);
visited[start] = true;
while (!q.empty())
{
int current = q.front();
printf("%d ", current + 1);
q.pop();
for (int next : relations[current])
{
if (!visited[next])
{
q.push(next);
visited[next] = true;
}
}
}
}
int main()
{
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int start;
cin >> N >> M >> start;
relations.resize(N);
visited = vector<bool>(N, false);
for (int i = 0; i < M; i++)
{
int f, s;
cin >> f >> s;
relations[f-1].push_back(s-1);
relations[s-1].push_back(f-1);
}
for (auto& r : relations)
sort(r.begin(), r.end());
dfs(start - 1);
visited.clear();
visited.resize(N);
printf("\n");
bfs(start - 1);
}
์ฌ๊ท๋ฅผ ํ์ฉํ dfs๋ ๊ฐ์ด ์์ผ๋ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
ํ๋ก๊ทธ๋๋จธ์ค ์์ ์์ถ
๋ค์์ ์์ฉ ๋ฌธ์ ์ ๋๋ค. ํ๋ก๊ทธ๋๋จธ์ค ์์ ์์ถ ๋ฌธ์ ์ ๋๋ค(๋งํฌ). PCCP ๊ธฐ์ถ๋ฌธ์ ๋ค์.

์ ์ถ๋ ฅ ์
| land | result |
| [[0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 0, 1, 1, 0], [1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1, 1]] | 9 |
| [[1, 0, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1]] | 16 |
์ฒซ๋ฒ์งธ ์์ ๋ ์ ๊ทธ๋ฆผ์ด๊ณ ๋ ๋ฒ์งธ ์์ ๋ ์๋ ๊ทธ๋ฆผ์ ๋๋ค.

Level 3์ ๊ฐ๊น์ด Level 2๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฐ์ Simple BFS์์๋ ๋
ธ๋์ง๋ง ๊ฒฉ์ ๋ชจ์์์๋ x,y์ขํ๊ฐ ๋ฐ๋ก ์๊ธฐ๋ ํฉ๋๋ค. ๋ํ์ ์ผ๋ก ๋ฏธ๋ก์ฐพ๊ธฐ, ๊ธธ์ฐพ๊ธฐ ๋ฌธ์ ์์๋ ๊ฒฉ์ ๋ชจ์์ ๋ฌธ์ ๊ฐ ๋ง์ด ๋์ค๊ธฐ๋ ํฉ๋๋ค.
๋ฌธ์ ์ ๊ทผ์ ํต์ฌ์ BFS๋ฅผ ํ์ฉํ์ฌ ๋ชจ๋ ์์ ๋ฉ์ด๋ฆฌ๋ค์ ํฉํ ๊ฐ(maxOil)์ ๊ตฌ์ฑํด ๋๋ ๊ฒ์
๋๋ค.
๋จผ์ ์ฒซ๋ฒ์งธ ํ๋ถํฐ ์ค๋ฅธ์ชฝ์ผ๋ก ์ํํ๋ฉด์ ์์ ๋ฅผ ๋ง๋ฌ๊ณ , ๋ฐฉ๋ฌธํ์ง ์์ง ์์๋ ๋ ธ๋๋ค์ ๋ํด์ bfs๋ฅผ ์งํํ๋ ๊ฒ์ด ์ฒซ ๋ฒ์งธ์ ๋๋ค.
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
int n, m;
vector<vector<bool>> visited;
int maxOil;
int solution(vector<vector<int>> land) {
n = land.size();
m = land[0].size();
visited.resize(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (land[i][j] == 1 && !visited[i][j]) {
maxOil = 0;
bfs(i, j, land);
...
๋ค์์ผ๋ก bfsํจ์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
// C++
...
int n, m;
vector<vector<bool>> visited;
int maxOil;
set<int> visitedColumns;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
void bfs(int i, int j, const vector<vector<int>>& land) {
visited[i][j] = true;
queue<pair<int, int>> q;
q.push(make_pair(i, j));
while(!q.empty()) {
auto current = q.front();
maxOil++;
//printf("[%d,%d] %d\n", current.first, current.second, maxOil);
visitedColumns.insert(current.second);
q.pop();
for (int i = 0; i < 4; i++) {
const int ci = current.first + dx[i];
const int cj = current.second + dy[i];
if (ci < 0 || ci >= n || cj < 0 || cj >= m)
continue;
if (land[ci][cj] == 1 && !visited[ci][cj]) {
q.push(make_pair(ci, cj));
visited[ci][cj] = true;
}
}
}
}
์์ ์์ถ ๋ฌธ์ ์ bfs์์ ์ธ์ ํ ๋ ธ๋๋ ํด๋น ๋ ธ๋์ ์ผ์ชฝ/์ค๋ฅธ์ชฝ/์์ชฝ/์๋์ชฝ 4๋ฐฉํฅ์ ๋๋ค. ๋ฐ๋ผ์ bfsํจ์์์๋ dx,dy๋ฅผ ์ด์ฉํด์ ๋ค ๋ฐฉํฅ์ ๋ํ ํ์์ ์์ํฉ๋๋ค. current i์ current j๊ฐ ๋์ด์ ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ , ๋ฐฉ๋ฌธํ์ง ์์ ์์ ๋ ์ ๋ชจ๋ ํ์ํฉ๋๋ค. ํ์ ํ ๋๋ง๋ค maxOil๊ฐ์ ๋๋ ค์ ์์ ๋ฉ์ด๋ฆฌ์ ํฉ์ ๊ตฌํด๋ ๋๋ค.
์ ์ฒด ์ฝ๋ ์ ๋๋ค.
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
int n, m;
vector<vector<bool>> visited;
int maxOil;
set<int> visitedColumns;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
void bfs(int i, int j, const vector<vector<int>>& land) {
visited[i][j] = true;
queue<pair<int, int>> q;
q.push(make_pair(i, j));
while(!q.empty()) {
auto current = q.front();
maxOil++;
//printf("[%d,%d] %d\n", current.first, current.second, maxOil);
visitedColumns.insert(current.second);
q.pop();
for (int i = 0; i < 4; i++) {
const int ci = current.first + dx[i];
const int cj = current.second + dy[i];
if (ci < 0 || ci >= n || cj < 0 || cj >= m)
continue;
if (land[ci][cj] == 1 && !visited[ci][cj]) {
q.push(make_pair(ci, cj));
visited[ci][cj] = true;
}
}
}
}
int solution(vector<vector<int>> land) {
n = land.size();
m = land[0].size();
visited.resize(n, vector<bool>(m, false));
vector<int> oilColumns(m, 0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (land[i][j] == 1 && !visited[i][j]) {
maxOil = 0;
visitedColumns.clear();
bfs(i, j, land);
for (const auto& v : visitedColumns) {
oilColumns[v] += maxOil;
}
//printf("\n");
}
}
}
return *max_element(oilColumns.begin(), oilColumns.end());
}
bfs๋ฅผ ์งํํ๊ธฐ ์ ์ ์ ์ญ๋ณ์์ธ maxOil๊ณผ visitedColumns๋ฅผ ์ด๊ธฐํ ์์ผ์ค๋๋ค. ๋ฌธ์ ์์ ์์ถ๊ด(์ด ๋ฐฉํฅ)์ด ์ถ์ถํ ์ ์๋ ์ต๋ ์์ ๋์ ๋ฌผ์ด๋ดค๊ธฐ ๋๋ฌธ์ ํ์ํ Column์ ์ ์ฅํ๋ visitedColumns์ Column๋ณ ์์ถ ๊ฐ๋ฅํ Oil์ ๊ธฐ๋กํ ์ ์๋ oilColumns๋ก ๊ตฌ์ฑํฉ๋๋ค. oilColumns์ ์ต๋๊ฐ์ด ์ ๋ต์ ๋๋ค.
BFS์ ์ฃผ์ ํน์ง์ ๋๋ค.
| ํญ๋ชฉ | ์ค๋ช |
| ํ์ ์์ | ์์ ๋ ธ๋ → ์ธ์ ๋ ธ๋ → ์ธ์ ๋ ธ๋์ ์ธ์ ๋ ธ๋ (๊ณ์ธต์ ํ์) |
| ์๋ฃ๊ตฌ์กฐ | ํ(Queue)๋ฅผ ์ฌ์ฉ |
| ์๊ฐ ๋ณต์ก๋ | O(V + E) (V: ์ ์ ์, E: ๊ฐ์ ์) |
| ๊ณต๊ฐ ๋ณต์ก๋ | O(V) (๋ฐฉ๋ฌธ ์ฌ๋ถ ๋ฐ ํ ์ ์ฅ์ฉ ๋ฉ๋ชจ๋ฆฌ) |
| ํ์ ๊ฒฐ๊ณผ | ์ต๋จ ๊ฒฝ๋ก(๊ฐ์ค์น๊ฐ ๋์ผํ ๊ฒฝ์ฐ)๋ฅผ ์ฐพ์ ์ ์์ |
| ๊ทธ๋ํ ํํ | ์ธ์ ๋ฆฌ์คํธ, ์ธ์ ํ๋ ฌ ๋ชจ๋ ๊ฐ๋ฅ |
| ์ฌ๊ท ์ฌ์ฉ ์ฌ๋ถ | ์ผ๋ฐ์ ์ผ๋ก ๋ฐ๋ณต๋ฌธ ๊ธฐ๋ฐ (DFS๋ ์ฌ๊ท ๊ธฐ๋ฐ์ธ ๊ฒฝ์ฐ ๋ง์) |
'์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [๋ฌธ์ ํ์ด/ํ๋ก๊ทธ๋๋จธ์ค] ์บ ํ (2017 ์นด์นด์ค์ฝ๋ ์์ ) (0) | 2025.10.24 |
|---|---|
| [DFS] ์ฌ๊ท์ ์คํ์ผ๋ก ๊ฐ๋ณ๊ฒ ๋ฌธ์ ํ๊ธฐ (1) | 2025.05.16 |
| [์คํ, ํ] ๋ฐฑํธ๋ํน(์ด์ ์ํ ๊ธฐ์ต)์ ์คํ์ ํ์ฉํ์ธ์ (0) | 2025.05.11 |
| [์ฐ์ ์์ ํ] ์ต์๊ฐ or ์ต๋๊ฐ ์ฐพ๊ธฐ ์๊ณ ๋ฆฌ์ฆ(feat. deque) (0) | 2025.04.13 |
| [๊ธฐ๋ณธ] ํฌ ํฌ์ธํฐ (0) | 2025.03.25 |