단진
대체로 맑음
단진
  • 분류 전체보기 (162)
    • 개발 (112)
      • 회고 (25)
      • 개발과정 (28)
      • 개념 (14)
      • JavaScript (11)
      • TypeScript (12)
      • 알고리즘 (4)
      • GitHub (4)
      • 오류 (9)
      • TMI (5)
    • 일상 (15)
      • 사진 및 여행 (6)
      • 책 소개 (4)
      • 기타 TMI (5)
    • IT (16)
      • 개념 (5)
      • 데이터베이스 (6)
      • 딥러닝 (1)
      • TMI (4)
    • TMI (4)
      • 법률 TMI (4)
    • 보안 (15)
      • Dreamhack (5)
      • Root Me (10)
hELLO · Designed By 정상우.
단진

대체로 맑음

[Algorithm] 그래프 탐색 - DFS & BFS
개발/알고리즘

[Algorithm] 그래프 탐색 - DFS & BFS

2022. 10. 21. 13:41

그래프 탐색

하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것

 


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
    '개발/알고리즘' 카테고리의 다른 글
    • [Algorithm] 매개변수 탐색
    • [Algorithm] 이진탐색 (바이너리 서치)
    • [Algorithm] 리스트와 딕셔너리
    단진
    단진

    티스토리툴바