오늘의 학습 키워드
그래프 탐색이란?
- 하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것
- Ex) 특정 도시에서 다른 도시로 갈 수 있는지 없는지, 전자 회로에서 특정 단자와 단자가 서로 연결되어 있는지
그러면 DFS란?
루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
https://www.acmicpc.net/problem/2644
위 입출력 예시1에 따르면 그래프의 그림은 이렇게 된다.
오름차순 방문: DFS 탐색 시 인접 정점들을 오름차순으로 방문.
1. 입력 처리
n = int(input()) # 전체 사람의 수
start, end = map(int, input().split()) # 촌수를 계산해야 하는 두 사람의 번호
m = int(input()) # 부모 자식 관계의 개수
n = int(input())
: 전체 사람의 수를 입력받는다.start, end = map(int, input().split())
: 촌수를 계산하고자 하는 두 사람의 번호를 입력받는다.m = int(input())
: 부모 자식 관계의 개수를 입력받는다.2. 그래프와 방문 기록 초기화
# 그래프와 방문 기록 초기화
graph = [[] for _ in range(n + 1)] # 각 사람의 관계를 나타내는 인접 리스트
visited = [False] * (n + 1) # 방문 여부를 기록하는 리스트
relation_depth = [] # 결과 촌수 저장 리스트
graph = [[] for _ in range(n + 1)]
: 각 사람 간의 관계를 나타내는 인접 리스트를 초기화한다. 사람들의 번호가 1부터 시작하므로 인덱스 0은 사용하지 않기 위해 n + 1 크기로 생성한다.visited = [False] * (n + 1)
: 각 사람이 방문되었는지 여부를 기록하는 리스트이다. 초기에는 모두 False로 설정되어 방문되지 않았음을 의미한다.relation_depth = []
: 두 사람 간의 촌수를 저장하기 위한 리스트이다. 목표 노드에 도달했을 때만 값을 추가한다.3. 부모 자식 관계 입력 및 그래프 구성
# 부모 자식 관계 입력 및 그래프 구성
for _ in range(m):
x, y = map(int, input().split())
graph[x].append(y)
graph[y].append(x)
for _ in range(m):
: 부모 자식 관계의 개수만큼 반복하여 관계를 입력받는다.x, y = map(int, input().split())
: 각 부모 자식 관계를 입력받아 x와 y로 저장한다.graph[x].append(y)
와 graph[y].append(x)
: 입력된 관계를 양방향으로 저장하여 두 사람 간의 연결을 표현한다. 이렇게 함으로써 무방향 그래프 형태로 관계를 나타낸다.4. 깊이 우선 탐색(DFS) 함수 정의
# 깊이 우선 탐색 (DFS) 정의
def dfs(current, depth):
depth += 1
visited[current] = True
if current == end:
relation_depth.append(depth)
return
for neighbor in graph[current]:
if not visited[neighbor]:
dfs(neighbor, depth)
def dfs(current, depth)
: 현재 방문 중인 노드와 현재까지의 깊이를 인자로 받는 DFS 함수이다.depth += 1
: 현재 노드의 깊이를 1 증가시킨다. 이는 촌수를 의미한다.visited[current] = True
: 현재 노드를 방문 처리하여 다시 방문하지 않도록 한다.if current == end
: 만약 현재 노드가 목표 노드와 일치한다면, relation_depth에 현재 깊이를 저장하고 탐색을 종료한다. 즉, 목표 노드에 도달했음을 의미한다.for neighbor in graph[current]
: 현재 노드와 연결된 모든 이웃 노드를 순회한다.if not visited[neighbor]
: 방문하지 않은 이웃 노드에 대해 재귀적으로 DFS를 호출하여 촌수를 계산한다.5. DFS 실행 및 결과 출력
# DFS 실행 및 결과 출력
dfs(start, 0)
# 촌수 계산 결과 출력
if len(relation_depth) == 0:
print(-1) # 친척 관계가 없는 경우
else:
print(relation_depth[0] - 1) # 촌수 출력 (depth에서 1을 뺌)
dfs(start, 0)
: 시작 노드와 깊이 0으로 DFS 탐색을 시작한다. 시작 노드에서부터 목표 노드까지의 촌수를 계산한다.if len(relation_depth) == 0
: 만약 목표 노드에 도달하지 못한 경우, 두 사람 간의 친척 관계가 없음을 의미하므로 -1을 출력한다.else: print(relation_depth[0] - 1)
: 목표 노드에 도달한 경우, 저장된 깊이에서 1을 빼서 최종 촌수를 출력한다. 깊이는 탐색 중 증가하기 때문에, 실제 촌수는 depth - 1이 된다.n = int(input()) # 전체 사람의 수
start, end = map(int, input().split()) # 촌수를 계산해야 하는 두 사람의 번호
m = int(input()) # 부모 자식 관계의 개수
# 그래프와 방문 기록 초기화
graph = [[] for _ in range(n + 1)] # 각 사람의 관계를 나타내는 인접 리스트
visited = [False] * (n + 1) # 방문 여부를 기록하는 리스트
relation_depth = [] # 결과 촌수 저장 리스트
# 부모 자식 관계 입력 및 그래프 구성
for _ in range(m):
x, y = map(int, input().split())
graph[x].append(y)
graph[y].append(x)
# 깊이 우선 탐색 (DFS) 정의
def dfs(current, depth):
depth += 1
visited[current] = True
if current == end:
relation_depth.append(depth)
return
for neighbor in graph[current]:
if not visited[neighbor]:
dfs(neighbor, depth)
# DFS 실행 및 결과 출력
dfs(start, 0)
# 촌수 계산 결과 출력
if len(relation_depth) == 0:
print(-1) # 친척 관계가 없는 경우
else:
print(relation_depth[0] - 1) # 촌수 출력 (depth에서 1을 뺌)
🔥 문제를 보고 dfs로 풀어야된다는 것은 바로 알게되었다..! 공부를 해서 그런가.. 하지만 코딩하기엔 아직 부족하고 어려운 점이 많아 정리를 하면서 다시 공부 중이다...!