Study with book/Algorithms

[백준]DFS와 BFS2


백준저지

[DFS와 BFS]https://www.acmicpc.net/problem/1260

DFS와 BFS는 총 3번에 걸쳐서 포스팅을 하려고 한다.

이번 포스팅에서는 BFS에 대한 설명을 위주로 하려고 한다.


전체 소스는

http://vvshinevv.tistory.com/12 를 참고하자.


본문에 들어가기에 앞서 DFSBFS를 구현하기 위해서는 그래프 자료구조를 구현할 수 있어야 한다.

필자는 그래프 표현 방법 인접 행렬인접리스트 인접리스트를 이용하였다.

아래 예시는 백준저지에서 예시로 제공한 것을 사용한다.


BFS(Breath First Search)

- 너비 우선 탐색으로 시작 정점으로부터 가장 가까운 정점을 먼저 전부 방문을 하고 멀리 떨어져 있는 정점을 제일 나중에 방문하는 순회 방법이다.

- BFS를 코딩하는 방법으로 Queue를 이용한 방식이 있다.

방법

- 백준 예시를 기준, 1을 제일 먼저 방문한다고 가정한다.

- 맨 왼쪽은 방문여부를 나타내는 배열, 아래쪽은 를 나타낸다.

- 회색이미 방문한 vertex, 분홍색방문 여부를 체크하는 중임을 나타낸다.

먼저 Main함수를 통해서 백준 예시를 입력하면 위 그림과 같이 2차원 배열이 생성된다.

※ vector STL에 대해 잘 모른다면일단 vec[0], vec[1]등 각 요소에 int형 배열을 담을 수 있다고만 생각하자.

※ Main함수는 전체 소스를 포스팅한 http://vvshinevv.tistory.com/12에 제시되어있다.

- BFS 함수를 호출하면 첫 번째 방문을 원하는 정점을 출력하고, 방문 여부를 True로 바꾸고 큐에 첫 방문 정점의 값(1)을 넣는다.

- 1과 인접한 정점 2에 대해서 방문 여부가 False이므로 방문을 시도한다.

- 정점 2를 방문하였으므로 2출력하고, 방문 여부를 True로 바꾸고 에 넣는다.

- 그리고 다음 인접한 정점 3에 대해 방문 여부를 체크한다.

DFSBFS의 차이점이 여기서 갈린다. DFS의 경우 방금 방문한 정점(여기서는 2)에 대해 인접한 정점(2에 인접한 정점은 1이므로 1이 방문 여부를 확인)을 찾고, BFS의 경우 이전에 방문한 정점(여기서는 1)에 전부 방문할 때 까지 방문 여부를 확인한다.

- 1과 인접한 정점 3에 대해서 방문 여부가 False이므로 방문을 시도한다.

- 정점 3를 방문하였으므로 3출력하고, 방문 여부를 True로 바꾸고 에 넣는다.

- 그리고 다음 인접한 정점 4에 대해 방문 여부를 체크한다.

- 1과 인접한 정점 4에 대해서 방문 여부가 False이므로 방문을 시도한다.

- 정점 4를 방문하였으므로 4출력하고, 방문 여부를 True로 바꾸고 에 넣는다.

- 그리고 다음 인접한 정점이 없으므로!!!!

- 위 그림과 같이 1pop하고 다음 방문할 정점은 2가 된다!!!

- 2와 인접한 모든 정점을 확인하고 전부 방문했으므로!!!!

- 위 그림과 같이 2pop하고 다음 방문할 정점은 3 된다!!!

- 3과 인접한 모든 정점을 확인하고 전부 방문했으므로!!!!

- 위 그림과 같이 3pop하고 다음 방문할 정점은 4 된다!!!

- 4와 인접한 모든 정점을 확인하고 전부 방문했으므로!!!!

- 위 그림과 같이 4 pop한다.

- 큐가 비어있으므로 함수를 리턴한다.



아래는 위 내용을 구현한 함수이다.

/**
* @brief: 넓이 우선 탐색
* @param: vector<int> vecArr[], bool visitArr[], int num, int fir
*
* vecArr: 그래프 나타내는 배열(by 인접 리스트)
* visitArr: 카드 섞을 때 중복을 방지하는 기준 배열
* num: 정점의 개수
* fir: 처음 방문할 정점 변수
*/
void ShowBFS(vector<int> vecArr[], bool visitArr[], int num, int fir) {
	queue<int> queue;
	int visit = fir;

	for (int i = 0; i <= num; i++)
		visitArr[i] = false;

	queue.push(fir); 
	VisitVertex(visitArr, fir);
	while (!vecArr[visit].empty()) {
		for (int i = 0; i < (int)vecArr[visit].size(); i++) {
			int next = vecArr[visit][i];
			if (visitArr[next] == false) {
				queue.push(next);
				VisitVertex(visitArr, next);
			}
		}
		queue.pop();
		if (!queue.empty()) {
			visit = queue.front();
		} else {
			break;
		}
	}
}


'Study with book > Algorithms' 카테고리의 다른 글

[백준]순열 사이클  (0) 2016.12.22
[백준]DFS와 BFS3  (0) 2016.12.22
[백준]DFS와 BFS1  (0) 2016.12.22
[백준]광고  (0) 2016.12.21
KMP 알고리즘  (7) 2016.12.02