Algorithm

[백준] 16940번: BFS 스페셜 저지- 파이썬

욜스터 2022. 4. 30. 18:02
728x90

https://www.acmicpc.net/problem/16940

 

16940번: BFS 스페셜 저지

올바른 순서는 1, 2, 3, 4와  1, 3, 2, 4가 있다.

www.acmicpc.net

문제

BOJ에서 정답이 여러가지인 경우에는 스페셜 저지를 사용한다. 스페셜 저지는 유저가 출력한 답을 검증하는 코드를 통해서 정답 유무를 결정하는 방식이다. 오늘은 스페셜 저지 코드를 하나 만들어보려고 한다.

정점의 개수가 N이고, 정점에 1부터 N까지 번호가 매겨져있는 양방향 그래프가 있을 때, BFS 알고리즘은 다음과 같은 형태로 이루어져 있다.

  1. 큐에 시작 정점을 넣는다. 이 문제에서 시작 정점은 1이다. 1을 방문했다고 처리한다.
  2. 큐가 비어 있지 않은 동안 다음을 반복한다.
    1. 큐에 들어있는 첫 정점을 큐에서 꺼낸다. 이 정점을 x라고 하자.
    2. x와 연결되어 있으면, 아직 방문하지 않은 정점 y를 모두 큐에 넣는다. 모든 y를 방문했다고 처리한다.

2-2 단계에서 방문하지 않은 정점을 방문하는 순서는 중요하지 않다. 따라서, BFS의 결과는 여러가지가 나올 수 있다.

트리가 주어졌을 때, 올바른 BFS 방문 순서인지 구해보자.

 

입력

첫째 줄에 정점의 수 N(2 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에는 트리의 간선 정보가 주어진다. 마지막 줄에는 BFS 방문 순서가 주어진다. BFS 방문 순서는 항상 N개의 정수로 이루어져 있으며, 1부터 N까지 자연수가 한 번씩 등장한다.

 

출력

입력으로 주어진 BFS 방문 순서가 올바른 순서면 1, 아니면 0을 출력한다.

 

풀이

사실 "양방향 그래프가 있을 때" 라고 했는데 갑자기 "트리가 주어졌을 때" 라고 써져있어서 매우 헷갈렸는데 이런 의미인거같다. 

이런 그래프가 있을 때, 시작 정점이 1이라고 했으니 트리로 보면 다음과 같다.

 

visited는 부모노드인지 확인하는 것이라고 생각하고 풀었다.

 

예를 들면 x가 3일 경우,

그래프에서 1, 4, 5가 연결되어 있는데 (GRAPH[3] = [1,4,5])

visited[4]와 visited[5]는 False지만 visited[1]는 True (=1이 3의 부모노드임)

 

answer의 idx부터 children 길이 만큼 children과 같은지 확인해보고 (자식노드들은 순서가 중요하지 않음 = sorted사용)

queue에 자식노드들을 넣어준다. (부모노드로 사용할거니까 visited[자식노드] = True)

 

답안코드

from collections import deque, defaultdict

def bfs():
    visited = [False] * (N+1)
    queue = deque()
    queue.append(1)
    visited[1] = True

    idx = 1
    while queue:
        x = queue.popleft()
        children = []

        for child in GRAPH[x]:
            if not visited[child]:
                visited[child] = True
                children.append(child)

        if sorted(answer[idx:idx+len(children)]) == sorted(children):
            for child in answer[idx:idx+len(children)]:
                queue.append(child)
            idx +=len(children)
        else:
            return 0
              
    return 1

GRAPH = defaultdict(list)

N = int(input())
for _ in range(N-1):
    start, end = map(int, input().split())
    GRAPH[start].append(end)
    GRAPH[end].append(start)

answer = list(map(int, input().split()))

if answer[0] == 1:
    print(bfs())
else:
    print(0)


오늘의 TMI

TMI 1: 며칠동안 이 문제를 못 풀다가 오늘 풀고야 말겠다는 의지로 무려 4시간동안 쳐다봄

TMI 2: 내일모레 면접있는데 코테공부하고 있음 🤪🤪

728x90
반응형