라떼는말이야

[백준 1260] DFS와 BFS 본문

알고리즘/코딩 테스트

[백준 1260] DFS와 BFS

MangBaam 2021. 8. 27. 17:48
반응형

문제

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

입력

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

출력

첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.

예제

예제


나의 풀이

DFS와 BFS의 기본적인 알고리즘에 대해서 묻는 문제이다. 기본 개념에 대해선 아래 글에서 설명 해놓았다.

DFS (깊이 우선 탐색)

2021.06.26 - 깊이 우선 탐색(DFS, Depth First Search) 파이썬 구현

 

깊이 우선 탐색(DFS, Depth First Search) 파이썬 구현

DFS의 용도 깊이 우선 탐색은 BFS와 마찬가지로 그래프를 방문하거나 탐색하는 방법 중 하나이다. 2021.05.23 - 너비 우선 탐색(BFS, Breadth First Search) 파이썬 구현 너비 우선 탐색(BFS, Breadth First Searc..

latte-is-horse.tistory.com

BFS (너비 우선 탐색)

2021.05.23 - 너비 우선 탐색(BFS, Breadth First Search) 파이썬 구현

 

너비 우선 탐색(BFS, Breadth First Search) 파이썬 구현

BFS (너비 우선 탐색, Breadth First Search) 최단 거리, 최소 비용과 같이 최솟값과 관련된 문제 해결에 사용. 이때 그래프의 가중치(시간, 비용, 거리 등)가 1이어야만 한다. 모든 경로에 대한 동시 탐색

latte-is-horse.tistory.com

 

이 문제를 풀 때 몇 가지 주의할 점이 있다.

  1. 문제에서 그래프를 입력 받는데, 출제자의 의도는 무방향 그래프를 의도한 것 같다. 즉, A 노드에 B를 추가했다면 A→B 가 아니라 A↔B 를 의미하기 때문에 A 노드에 B를 추가하고, B 노드에도 A 노드를 추가해야 한다.
  2. 1번에서 추가한 노드들이 중복될 수도 있다. 이때 중복 제거를 해주고, 문제의 조건에 따라 오름차순으로 정렬해줘야 한다.
  3. 방문 표시를 하기 위해 visited라는 리스트를 사용하는데 한 번 사용된 visited는 초기화를 해주던가 아니면 다른 변수로 다뤄야 한다.

위 3가지를 제외하면 가장 일반적인 형태의 DFS와 BFS를 묻는 문제이다.

main 코드

n, m, v = map(int, input().split())
graph = [[] for _ in range(n+1)]
visited = [False] * (n+1)
for _ in range(m):
    root, leaf = map(int, input().split())
    graph[root].append(leaf) # 무방향 그래프
    graph[leaf].append(root) # 서로 추가해준다
graph = [sorted(set(x)) for x in graph] # 중복 제거 후 오름차순 정렬
print(graph)
print()
dfs(graph, v)
print()
bfs(graph, v)

위에서 설명한대로 root 값과 leaf 값을 받으면 두 노드에 서로 추가한다.

이후 set() 메소드로 중복 제거 후 sorted로 오름차순 정렬을 해서 graph를 준비한다.

BFS 코드

from collections import deque
def bfs(graph, start):
    visited_bfs = [False] * (n+1) # n은 사용자에게 입력 받는다
    queue = deque([start])
    visited_bfs[start] = True
    while queue:
        x = queue.popleft()
        print(x, end=' ')
        for i in graph[x]:
            if not visited_bfs[i]: queue.append(i)
            visited_bfs[i] = True

DFS 코드

visited = [False] * (n+1) # n은 사용자에게 입력 받는다
def dfs(graph, start):
    visited[start] = True
    print(start, end=' ')
    for i in graph[start]:
        if not visited[i]:
            dfs(graph, i)

 


전체 코드

from collections import deque
# BFS
def dfs(graph, start):
    visited[start] = True
    print(start, end=' ')
    for i in graph[start]:
        if not visited[i]:
            dfs(graph, i)
# DFS
def bfs(graph, start):
    visited_bfs = [False] * (n+1)
    queue = deque([start])
    visited_bfs[start] = True
    while queue:
        x = queue.popleft()
        print(x, end=' ')
        for i in graph[x]:
            if not visited_bfs[i]: queue.append(i)
            visited_bfs[i] = True
# main
n, m, v = map(int, input().split())
graph = [[] for _ in range(n+1)]
visited = [False] * (n+1)
for _ in range(m):
    root, leaf = map(int, input().split())
    graph[root].append(leaf) # 무방향 그래프
    graph[leaf].append(root) # 서로 추가해준다
graph = [sorted(set(x)) for x in graph] # 중복 제거 후 오름차순 정렬
# Execute
dfs(graph, v)
print()
bfs(graph, v)

채점 결과

 

반응형
Comments