728x90
반응형
1260번: DFS와 BFS
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사
www.acmicpc.net
1. 문제 설명
2. 풀이과정
리스트를 만들어 각 정점의 값을 [False]로 설정한 뒤, 탐색한 정점을 True로 바꾸면서 모든 정점의 값이 True가 될 때까지 탐색한다.
DFS는 재귀 알고리즘을 사용하여 계속적으로 정점에 이어진 정점을 탐색하고 탐색할 정점이 없다면 다음 정점으로 넘어가 탐색을 계속한다.
BFS는 deque을 사용하여 정점에서 연결된 모든 정점을 탐색하고 연결된 정점 중 가장 작은 정점으로 넘어가 탐색을 계속한다.
- sys.stdin.readline() 함수를 사용하기 위해 sys 라이브러리를 불러온다. import sys
- BFS 탐색에서 덱(deque) 자료구조 사용을 위해 deque()을 활용한다. 따라서 collections 라이브러리의 deque() 메서드를 불러온다. from collections import deque
- DFS 함수와 BFS 함수를 생성한다. (함수는 아래에서 자세하게 설명)
- 정점의 개수, 간선의 개수, 탐색을 시작할 정점의 번호를 입력받는다. N, M, V = map(int, sys.stdin.readline().split())
- 각 정점별로 연결된 정점을 저장할 리스트를 만든다. graph = list()
- 이 리스트는 2차원 배열로 만들어져야 한다. for _ in range(N): graph.append([])
- 간선의 개수만큼 반복하여 for _ in range(M)
- 간선의 정보를 입력받는다. v1, v2 = map(int, sys.stdin.readline().split())
- 입력받은 간선의 정보를 리스트에 저장한다. 여기서 생성한 리스트는 0번부터 인덱스가 시작되므로 입력받은 간선 정보의 정점 번호에서 1 빼준 위치에 1 빼준 값을 추가해줘야 한다. graph[v1 - 1].append(v2 - 1) graph[v2 - 1].append(v1 - 1)
- 간선 정보까지 입력된 리스트를 오름차순으로 정렬한다. for i in graph: i.sort()
- 각 정점별 탐색 결과를 저장할 리스트를 생성하고 False로 초기화한다. result = [False] * N
- 시작 정점의 인덱스 값을 인수로 한 DFS 탐색을 수행한다. DFS(V - 1)
- 다음 BFS 출력을 위해 출력되는 줄을 다음 줄로 줄 바꿈 해준다. print()
- 각 정점별 탐색 결과를 저장할 리스트를 다시 생성하고 False로 초기화한다. result = [False] * N
- 시작 정점의 인덱스 값을 인수로 한 BFS 탐색을 수행한다. BFS(V - 1)
DFS 탐색 함수
- 매개변수로 탐색의 시작 정점을 입력받는 DFS 함수를 생성한다. def DFS(start)
- 탐색 결과 리스트에서 입력받은 시작 정점의 인덱스 위치를 True로 바꿔준다. result[start] = True
- 시작 정점의 값을 줄 바꿈 없이 공백을 두고 출력한다. print(start + 1, end=' ')
- 해당 시작 정점과 연결되어 있는 정점들을 순서대로 탐색한다. for i in graph[start]
- 만약 추출한 인접 정점의 탐색 결과가 아직 False이면 해당 정점을 시작 정점으로 하는 DFS 탐색을 먼저 수행한다. (DFS 깊이 우선 탐색 과정) if (not result[i]): DFS(i)
BFS 탐색 함수
- 매개변수로 탐색의 시작 정점을 입력받는 BFS 함수를 생성한다. def BFS(start)
- 시작 정점이 원소로 있는 덱(deque)을 생성한다. queue = deque([start])
- 탐색 결과 리스트에서 입력받은 시작 정점의 인덱스 위치를 True로 바꿔준다. result[start] = True
- 생성한 deque이 공백이 될 때까지 반복한다. while (queue)
- deque에서 가장 왼쪽 원소를 추출한다. v = queue.popleft()
- 추출한 값은 시작 정점과 연결된 정점 중 가장 작은 정점의 인덱스 값이며 해당 정점의 값을 줄 바꿈 없이 공백을 두고 출력한다. print(v + 1, end=' ')
- 추출한 정점과 연결되어 있는 정점들을 순서대로 탐색한다. for i in graph[v]
- 만약 추출한 인접 정점의 탐색 결과가 아직 False이면 if (not result[i])
- 해당 정점의 탐색 결과를 True로 바꾸고 result[i] = True
- deque에 추가한다. queue.append(i)
반응형
3. 소스코드
import sys
from collections import deque
def DFS(start):
result[start] = True
print(start + 1, end=' ')
for i in graph[start]:
if (not result[i]):
DFS(i)
def BFS(start):
queue = deque([start])
result[start] = True
while (queue):
v = queue.popleft()
print(v + 1, end=' ')
for i in graph[v]:
if (not result[i]):
result[i] = True
queue.append(i)
N, M, V = map(int, sys.stdin.readline().split())
graph = list()
for _ in range(N):
graph.append([])
for _ in range(M):
v1, v2 = map(int, sys.stdin.readline().split())
graph[v1 - 1].append(v2 - 1)
graph[v2 - 1].append(v1 - 1)
for i in graph:
i.sort()
result = [False] * N
DFS(V - 1)
print()
result = [False] * N
BFS(V - 1)
728x90
반응형
'백준' 카테고리의 다른 글
[백준] 11399번 : ATM - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.09 |
---|---|
[백준] 10870번 : 피보나치 수 5 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.07 |
[백준] 10817번 : 세 수 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.07 |
[백준] 2869번 : 달팽이는 올라가고 싶다 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.07 |
[백준] 2751번 : 수 정렬하기 2 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.04 |
[백준] 1712번 : 손익분기점 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.03 |
[백준] 2941번 : 크로아티아 알파벳 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.03 |
[백준] 2798번 : 블랙잭 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트 (0) | 2023.07.03 |