

정글에선 넓고 얕은 인간관계와 좁고 깊은 인간관계 사이에서 고민을 하게 됩니다.
하지만 DFS든 BFS든 모든 노드를 만나듯, 어떻게든 모두랑 친해질 수 있지 않을까요?
제가 어느 쪽을 더 좋아하는지는 비밀로 하겠습니다.





# 인접 리스트
graph = [
[], # 0번노드는 사용 안 함
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
# 각 노드의 방문 여부
visited = [False] * 9
graph 2차원 리스트로, 그래프를 인접 리스트 형태로 표현graph[i]는 시작 노드 i와 연결된 인접 노드의 리스트graph[0]은 편의상 비워둠graph[1] -> [2, 3, 8]: 1번 노드는 2, 3, 8번 노드와 연결됨visited 리스트로 각 노드의 방문 여부를 표현visited[i]가 True면 i번 노드를 방문했고, False면 방문하지 않은 상태def dfs(graph, x, visited):
# (1) 노드 x를 방문 처리
visited[x] = True
print(x, end=" ")
# (2) 미방문한 인접 노드를 재귀적으로 방문
for i in graph[x]: # 노드 x의 인접 노드 순회
if not visited[i]: # 인접 노드가 미방문 노드인 경우
dfs(graph, i, visited) # 재귀 호출
dfs(x) 함수는 x번 노드를 방문하고, 미방문한 인접 노드 i를 재귀적으로 방문dfs(i)가 실행되는 동안에도 dfs(x)은 아직 종료되지 않았음i 밑에 노드 x가 남아 있는 것과 유사dfs(i)가 종료되면, 이전에 호출된 dfs(x)로 돌아오게 됨# DFS 함수 호출
dfs(graph, 1, visited) # 1 2 7 6 8 3 4 5
1번 노드부터 DFS 탐색을 시작1 -> 2 -> 7 -> 6 -> 8 -> 3 -> 4 -> 5



⚠️ BFS는 시작 노드와의 거리가 가까운 노드부터 탐색합니다.
(1) 방문(2, 3, 8) 방문(7, 4, 5) 방문(6) 방문1로 동일하게 간주할 수 있다는 점 기억하시죠?graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
# 시작 노드와의 거리. 방문하지 않은 노드는 None.
distance = [None] * 9
🤗 BFS로 거리 순으로 노드를 반환한다는 특징을 이용해, 이번엔 visited 말고 distance 배열을 만들어 보겠습니다.
distance[i]엔, i번째 노드를 방문할 때 i번 노드와 시작 노드 간 거리를 계산해 저장None으로 표시from collections import deque
def bfs(graph, start, distance):
# 큐에 시작 노드를 삽입
queue = deque([start])
# 시작 노드와 시작 노드 간 거리는 0
distance[start] = 0
while queue:
# 큐에서 노드 x를 꺼냄
x = queue.popleft()
print(x, end=" ")
# 아직 방문하지 않은 인접 노드 탐색
for i in graph[x]:
if distance[i] is None:
# 모두 큐에 삽입
# 거리: 현재 노드의 거리 + 1
queue.append(i)
distance[i] = distance[x] + 1
deque를 이용해서 큐를 구현할 수 있음0으로 둠현재 노드의 거리 + 1로 계산distance[i]가 None인지 아닌지로 체크bfs(graph, 1, distance) # 1 2 3 8 7 4 5 6
print("\n거리 정보")
for i in range(1, 9):
print(f"{i}번 노드: {distance[i]}")
# 거리 정보
# 1번 노드: 0
# 2번 노드: 1
# 3번 노드: 1
# 4번 노드: 2
# 5번 노드: 2
# 6번 노드: 3
# 7번 노드: 2
# 8번 노드: 1
🤔 왜 DFS, BFS를 구현할 때 인접 행렬이 아니라 인접 리스트를 사용하나요?

🐶 단순히 모든 노드를 탐색해야 하는 경우
sys.setrecursionlimit()로 깊이 제한을 늘려 줘야 하는 번거로움이 있습니다.🐶 노드 간 최단 거리를 확인해야 하는 경우
🐶 [경우의 수를 찾아야 하는 경우]

2 선택)3로 고를지, 4로 고를지)로 볼 수 있습니다.import sys
from collections import deque
sys.setrecursionlimit(10 ** 6)
N, M, V = map(int, input().split())
graph = [[] for _ in range(N + 1)]
visited_dfs = [False] * (N + 1)
visited_bfs = [False] * (N + 1)
# 양방향임에 유의하기
for _ in range(M):
a, b = map(int, input().split())
graph[a].append(b)
graph[b].append(a)
for i in range(1, N + 1):
graph[i].sort()
# DFS
def dfs(x, graph, visited):
print(x, end=" ")
visited[x] = True
for i in graph[x]:
if not visited[i]:
dfs(i, graph, visited)
dfs(V, graph, visited_dfs)
print()
# BFS
def bfs(start, graph, visited):
queue = deque([start])
visited[start] = True
while queue:
x = queue.popleft()
print(x, end=" ")
for i in graph[x]:
if not visited[i]:
queue.append(i)
visited[i] = True
bfs(V, graph, visited_bfs)
graph[a].append(b), graph[b].append(a) 양쪽 다 해 줘야 함에 유의graph 내 리스트를 모두 정렬해야 함백준 / 실버 2 / 18352. 특정 거리의 도시 찾기
from collections import deque
import sys
input = sys.stdin.readline
# 도시, 도로, 목표 최단거리, 출발 도시
N, M, K, X = map(int, input().split())
graph = [[] for _ in range(N + 1)]
# 인접 리스트
for _ in range(M):
a, b = map(int, input().split())
graph[a].append(b)
# 각 도시의 거리정보. 미방문 시 None
dist = [None] * (N + 1)
def bfs(graph, start, dist):
dist[start] = 0 # 출발 도시의 거리는 0
queue = deque([start])
while queue:
i = queue.popleft()
for j in graph[i]:
if dist[j] is None:
# 인접 도시의 거리는
# 현재 도시의 거리 + 1로 계산
dist[j] = dist[i] + 1
queue.append(j)
bfs(graph, X, dist)
# 최단 거리가 K
count = 0
for i in range(1, N + 1):
if dist[i] == K:
print(i)
count += 1
if count == 0:
print(-1)