CodingTest/BOJ

백준 1260 DFS와 BFS - Python

사족보행 개발자 2024. 12. 5. 23:06
728x90

DFS와 BFS

 

문제

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 

단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 

더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

입력

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 

다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 

 

어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

출력

첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. 

V부터 방문된 점을 순서대로 출력하면 된다.

 

문제풀이

간단한 DFS, BFS 풀이 문제이다.

두 알고리즘을 구현할 수 있는지에 대한 기본 지식을 묻는 문제 같았다.

 

DFS는 stack을 기반으로 간선을 기반으로 노드를 순회하고

BFS는 queue를 기반으로 노드를 순회한다.

 

따라서 visited 배열을 통해 이미 순회한 노드가 중복되지 않도록 하며,

각 간선의 정보는 adj에 dictionary의 형태로 저장했다.

 

간선 정보를 기반으로 순회하는 깔끔한 문제였다.

그래서 standard인것 같다.

 

여기서 순회가능한 노드가 여러개일 때, 노드 번호가 낮은 순으로 순회해야 하므로,

다음 순회할 노드를 위해 간선정보를 확인할 때,

번호의 오름차순으로 들어갈 수 있게, 이를 정렬했다.

 

여기서 stack과 queue의 자료구조를 이해하고 있다면,

두 알고리즘(BFS, DFS) 간선 정보의 정렬은 반대로 되어야 한다는 점을 이해해야 한다.

 

이를 기반으로 확인하면 문제는 쉽게 해결할 수 있다.

 

정답코드

from collections import deque

def dfs(v, adj, visited):
    stack = [v]
    dfs_result = []
    
    while stack:
        node = stack.pop()
        if not visited[node]:
            visited[node] = True
            dfs_result.append(node)
            # 인접 노드를 역순으로 스택에 추가하여 작은 숫자부터 방문
            stack.extend(sorted(adj[node], reverse=True))
    
    return dfs_result

def bfs(v, adj, visited):
    queue = deque([v])
    bfs_result = []
    visited[v] = True
    
    while queue:
        node = queue.popleft()
        bfs_result.append(node)
        # 인접 노드를 정렬하여 큐에 추가하여 작은 숫자부터 방문
        for next_node in sorted(adj[node]):
            if not visited[next_node]:
                visited[next_node] = True
                queue.append(next_node)
                
    return bfs_result

n, m, v = map(int, input().split())
adj = {i: [] for i in range(1, n + 1)}

for _ in range(m):
    s, e = map(int, input().split())
    adj[s].append(e)
    adj[e].append(s)

# DFS 수행
visited = [False] * (n + 1)
dfs_result = dfs(v, adj, visited)
print(' '.join(map(str, dfs_result)))

# BFS 수행
visited = [False] * (n + 1)
bfs_result = bfs(v, adj, visited)
print(' '.join(map(str, bfs_result)))
728x90