(C++) 백준 1260번 - DFS와 BFS

코딩너구리·2025년 10월 23일

코딩 문제 풀이

목록 보기
47/266

https://www.acmicpc.net/problem/1260

문제

> 그래프를 DFS, BFS로 탐색한 결과를 출력해라.
> 단 방문할 수 있는 정점이 여러개면 번호가 작은것먼저 방문하고 더 이상 방문 할 수 있는 점이 없으면 종료한다.
> 정점 수, 간선 수, 시작번호가 입력이다.
> M개의 줄엔 간선이 연결하는 두 정점의 번호가 주어진다.

접근

DFS(Depth-First-search), BFS(Breadth-First-search)를 각각 구현해 주어진 노드, 간선, 시작점으로 탐색한다.

문제해결

> 점과 간선을 담을 이중벡터 dots와 방문처리를 위한 bool 벡터 dot을 선언해주고 BFS와 DFS를 함수로 구현한다.
> 문제에서 주어진 입력을 모두 받는다. 전역으로 선언한 벡터들을 assign을 통해 크기와 초기값을 지정해준다.
> 양방향 그래프이므로 입력받은 점, 간선에 대해 두가지로 벡터에 저장한다.
> 입력받은 점을 작은값부터 차례대로 탐색하기위해 정렬해주고 DFS와 BFS에 시작점으로 받은 V를 넣어 호출한다.
> 각 함수 사이에 fill을 이용해 dot 부울 벡터의 값을 다시 false로 전부 초기화 해줘야 제대로 값을 얻을 수 있다.

문제해결(BFS)

> BFS는 큐를 사용하며 먼저 시작점을 입력받아 큐에 넣는다.
> 인접한 노드, 미방문 노드가 없으면 큐가 비기때문에 empty()가 될때 까지 while문을 돌린다.
> 큐의 가장 앞에있는 값을 먼저 탐색을 한다. 큐에서 제거해주면서 만약 탐색했던 점이면 다음 탐색으로 넘어가고 아니면 해당 점을 출력해주고 방문처리를 한다. 이제 해당 점의 갈 수 있는 경로를 전부 탐색해 방문한적 없는 경로만 큐에 넣는다.
> 위 탐색을 반복하면 탐색했던 점은 걸러지며 탐색 순서대로 출력이 나온다.

문제해결(DFS)

> DFS는 스택 또는 재귀를 사용한다. 난 스택을 사용했다. 먼저 시작점을 입력받아 큐에 넣는다.
> 동작 자체는 BFS와 유사하다. 스택이 빌 때까지 반복해주며 스택에 들어온 값중 상단, 젤 나중에 들어온 값을 가져오고 제거한다. 스택은 LIFO(선입후출)이기 떄문이다.
> 그 점이 방문헀던 점이면 스택에 있는 다음 값으로 넘어가고 아니라면 해당 점의 다음 경로를 탐색한다.
> 문제에 방문할 수 있는 정점이 여러개면 번호가 작은 정점 부터 방문하라고 했으므로 해당 점의 가능 경로 중 큰수부터 스택에 넣기위해 역순으로 반복문을 돌려준다.(스택이므로)
> 방문했던 점이면 넘기고 안했으면 스택에 넣어준다.
> 위 과정을 반복한다.

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
using namespace std;

vector<vector<int>> dots;
vector<bool> dot;
void BFS(int start)
{
	queue<int> q;
	q.push(start);
	while (!q.empty())
	{
		int d = q.front();
		q.pop();

		if (dot[d])
			continue;

		cout << d << " ";
		dot[d] = true;

		for (int i : dots[d])
		{
			if (!dot[i])
			{ 
				q.push(i);
			}
		}
	}
}
void DFS(int start)
{
	stack<int> s;
	s.push(start);
	while (!s.empty())
	{
		int d = s.top();
		s.pop();

		if (dot[d])
			continue;
		cout << d << " ";
		dot[d] = true;

		for (auto it = dots[d].rbegin(); it != dots[d].rend(); ++it)
		{
			if (!dot[*it])
				s.push(*it);
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int N, M, V;
	cin >> N >> M >> V;
	dot.assign(N + 1, false);
	dots.assign(N + 1, vector<int>());
	for (int i = 0; i < M; i++)
	{
		int x, y;
		cin >> x >> y;
		dots[x].push_back(y);
		dots[y].push_back(x);
	}
	for(int i = 1; i <= N; i++)
		sort(dots[i].begin(), dots[i].end());
	DFS(V);
	cout << '\n';
	fill(dot.begin(), dot.end(), false);
	BFS(V);
}

후기

이 문제를 통해 DFS와 BFS를 처음 배웠다. 처음엔 이해하는데 복잡했지만 계속 함수 내 반복문, 탐색과정을 따라다니다 보니 이해하게 되었다.
이 문제를 통해 알게 된 BFS로 최근 푼 미로탐색 문제도 풀 수 있었다.

0개의 댓글