그래프 탐색
하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것
DFS (Depth First Search: 깊이우선탐색)
- 스택 사용
- 특정 노드에서 시작해서 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
- 모든 노드를 방문하고자 하는 경우에 이 방법을 선택
- 깊이 우선 탐색이 너비 우선 탐색보다 좀 더 간단하다
- 검색 속도 자체는 너비 우선 탐색(BFS)보다 느리다
- 순환 알고리즘(재귀 함수) 형태를 가지고 있다
- 어떤 노드를 방문했었는지 여부를 반드시 검사해야 한다
- 이 과정을 생략하면 무한루프에 빠질 수 있다
- 정점의 수: N, 간선의 수: E인 경우 시간 복잡도
- 인접 리스트로 표현된 그래프 : O(E+N)
- 인접 행렬로 표현된 그래프 : O(N^2)
BFS (Breadth First Search: 너비우선탐색)
- 큐 사용
- 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문
- 두 노드 사이의 최단 경로 혹은 임의의 경로를 찾고 싶을 때 이 방법을 선택한다
- 재귀적으로 작동하지 않는다
- 어떤 노드를 방문했었는지 여부를 반드시 검사해야 한다
- 이 과정을 생략하면 무한루프에 빠질 수 있다
- 시간 복잡도
- 인접 리스트로 표현된 그래프 : O(N+E)
- 인접 행렬로 표현된 그래프 : O(N^2)
예제
BOJ 1260 - DFS와 BFS
문제
그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.
입력
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.
출력
첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.
예제 입력
4 5 1
1 2
1 3
1 4
2 4
3 4
예제 출력
1 2 4 3
1 2 3 4
코드
from collections import deque
N, M, V = map(int, input().split())
l = [[] for _ in range(N+1)]
dq = deque()
start = V
def DFS(start): # 재귀 방식
if visit[start] != 1:
visit[start] = 1
print(start, end=" ")
for i in l[start]:
if visit[i] != 1:
DFS(i)
def BFS(start): # 큐 이용
dq.append(start)
visit[start] = 1
while dq:
start = dq.popleft()
for i in l[start]:
if visit[i] != 1:
dq.append(i)
visit[i] = 1
print(start, end=" ")
for _ in range(M):
a, b = map(int, input().split())
l[a].extend([b])
l[a].sort()
l[b].extend([a])
l[b].sort() # 인접 리스트 방식
visit = [0 for _ in range(N + 1)]
DFS(V)
print()
visit = [0 for _ in range(N + 1)]
BFS(V)
'개발 > 알고리즘' 카테고리의 다른 글
[Algorithm] 매개변수 탐색 (0) | 2022.10.24 |
---|---|
[Algorithm] 이진탐색 (바이너리 서치) (0) | 2022.10.23 |
[Algorithm] 리스트와 딕셔너리 (0) | 2022.09.30 |