문제
문제 이해
DFS는 스택으로 BFS는 큐로 해결할 수 있습니다.
컴퓨터 내부에서 재귀함수의 수행은 스택 자료구조를 이용합니다. 함수를 계속 호출했을 떄 가장 마지막에 호출한 함수가 먼저 수행을 끝내야 그 앞의 함수 호출이 종료가 됩니다.
즉, 제귀로 깔끔한 코드를 짤 수 있습니다.
먼저 DFS 코드입니다.
#DFS 메서드 정의
def dfs(graph, v, visited):
#현재 노드를 방문 처리
visited[v] = True
print(v, end=' ')
#현재 노드와 연결된 다른 노드를 재귀적으로 방문
for i in graph[v]:
if not visited[i]:
dfs(graph, i, visited)
여기서 graph는 2차원 배열입니다.
- 처음에 시작인 v노드를 거치고
- graph배열 안에 있는 주변 노드를 검색합니다.
- 만약 방문(visited[]에 True)했다면 건너 뛰고
- 아니라면 제귀를 호출해 스택에 넣습니다.
BFS 코드입니다.
#BFS 메서드 정의
def bfs(graph, start, visited):
#큐 구현을 위해 deque 사용
queue = deque([start])
#현재 노드를 방문 처리
visited[start] = True
#큐가 빌때 까지 반복
while queue:
#큐에서 하나의 원소를 뽑아 출력
v = queue.popleft()
print(v, end=' ')
#해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입
for i in graph[v]:
if not visited[i]:
queue.append(i)
visited[i] = True
이건 큐를 이용합니다.
- 큐에 start 노드를 집어 넣습니다.
- 그리고 방문했다고 도장을 찍습니다.
- 이제 큐에서 작업을 시작합니다. 큐가 비어있다면 탐색을 마친겁니다.
- 큐에서 하나를 뽑습니다. 파이선 list는 오른쪽에서만 들어가고 오른쪽에서만 뺄 수 있는데, deque는 왼쪽에서 뽑을 수 있게 popleft를 지원합니다. 우리는 큐를 사용하기 때문에 먼저들어온것(왼쪽)을 뽑아야 합니다.
- 하나 뽑은것의 주변을 (graph[]) 살펴봅니다. 주변에 도장이 찍혀 있다면 넘어가지만
- 안찍혀 있다면 큐의 집어 넣습니다. (이 때는 오른쪽으로 들어갑니다.)
- 큐에 집어넣음과 동시에 도장을 찍습니다.
주변에 있는 모든것을 큐에 넣는다는 계념을 배웟습니다.
전체 코드
from collections import deque
N, M ,V = map(int,input().split())
#DFS 메서드 정의
def dfs(graph, v, visited):
#현재 노드를 방문 처리
visited[v] = True
print(v, end=' ')
#현재 노드와 연결된 다른 노드를 재귀적으로 방문
for i in graph[v]:
if not visited[i]:
dfs(graph, i, visited)
#BFS 메서드 정의
def bfs(graph, start, visited):
#큐 구현을 위해 deque 사용
queue = deque([start])
#현재 노드를 방문 처리
visited[start] = True
#큐가 빌때 까지 반복
while queue:
#큐에서 하나의 원소를 뽑아 출력
v = queue.popleft()
print(v, end=' ')
#해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입
for i in graph[v]:
if not visited[i]:
queue.append(i)
visited[i] = True
#각 노드가 연결된 정보를 리스트 자료형으로 표현(2차원 리스트)
graph = [[] for _ in range(N+1)]
for i in range(M):
node, link = map(int,input().split())
graph[node].append(link)
graph[link].append(node)
graph[node].sort()
graph[link].sort()
#각 노드가 방문된 정보를 리스트 자료형으로 표현(1차원 리스트)
visited = [False] * int(N+1)
#정의된 DFS 함수 호출
dfs(graph, V, visited)
visited = [False] * int(N+1)
print()
#정의된 bfs 함수 호출
bfs(graph, V, visited)
사실 graph계념을 정리해는데 어려웟씁니다. 하나의 노드에만 연결관계를 알려주니 길이 끊기는 일이 있더군요. 노드의 관계를 설정할 때 양 노드 모두에게 연결이 되었다는 것을 설정해야 합니다.
여기서는 append()할 때 양쪽 모두에게 넣었습니다.
그리고 작은 것 부터 순서대로 탐색을 해야하니 sort()를 사용했습니다. 이러면 숫자가 작은것 부터 정렬이 됩니다.
728x90
'알고리즘 > 백준알고리즘' 카테고리의 다른 글
[백준 알고리즘/Python] 4963 섬의 개수 (0) | 2022.02.22 |
---|---|
[백준 알고리즘/Python] 11724 연결 요소의 개수 (0) | 2022.02.21 |
[백준 알고리즘/Python] 1748 수 이어 쓰기1 (0) | 2022.02.18 |
[백준 알고리즘/Python] 6064 카잉 달력 (0) | 2022.02.16 |
[백준 알고리즘/Python] 1107 리모컨 (0) | 2022.02.16 |