[PS] BOJ 3865 / 학회원
문제 링크: https://www.acmicpc.net/problem/3865
그래프 탐색을 응용하는 문제입니다.
풀이
파싱 + 그래프 탐색
파싱을 통해 유향 그래프를 만들어낸 뒤, 그래프 탐색으로 진출 차수가 0인 정점의 개수를 세면 됩니다.
1) 파싱
먼저, 입력 데이터는 다음과 같이 구성됩니다.
N
academy_name:member1,member2,...,memberK.
... (repeated N-1 times)입력 데이터 구조
$N$은 입력으로 주어지는 학회의 수이고, 각 학회의 입력에 주어지는 학회원 명단은 최대 10명입니다. 각 멤버의 이름은 ,로 구분되며, 각 줄의 끝에는 마침표가 붙습니다.
edges = {}
text = input().rstrip()[:-1] # 마지막 1글자는 마침표이므로 제외
academy_name, member_names = text.split(":") # 학회 이름과 학회원 명단 분리
edges[academy_name] = member_names.split(",") # 학회원 이름 분리학회 이름과 멤버 이름 분리하기
정규식을 사용해도 되지만, 간단한 구조를 고려해 문자열을 쪼개는 방식으로 구현했습니다.
각 학회에 대한 입력은 (학회명) → (학회원)의 유향 그래프 형태로 저장됩니다.
그래프 탐색
이후, 입력을 파싱해 만든 유향 그래프에 대해 그래프 탐색을 진행해주면 됩니다. 저는 BFS로 진행했습니다.
cnt = 0
visited = {}
# BFS to resolve member count
queue.append(target_academy) # 첫 번째로 주어진 학회의 이름에 대해 학회원 수 구하기
while queue:
name = queue.popleft()
for m in edges[name]:
if not visited.get(m, False): # 아직 방문하지 않은 정점에 대해
visited[m] = True
if edges.get(m, None) is not None and len(edges[m]) > 0: # 진출 차수가 0이 아니라면, 학회 이름이므로 큐에 추가
queue.append(m)
else: # 진출 차수가 0인 정점은 학회원의 이름이다.
cnt += 1
print(cnt)BFS
전체 코드
from collections import deque
input = open(0).readline
cnt = 0
edges = {}
visited = {}
target_academy = ""
queue = deque()
while True:
N = int(input())
if N == 0:
break
cnt = 0
edges.clear()
visited.clear()
for i in range(N):
text = input().rstrip()[:-1]
academy_name, member_names = text.split(":")
if i == 0:
target_academy = academy_name
edges[academy_name] = member_names.split(",")
# BFS to resolve member count
queue.append(target_academy)
while queue:
name = queue.popleft()
for m in edges[name]:
if not visited.get(m, False):
visited[m] = True
if edges.get(m, None) is not None and len(edges[m]) > 0:
queue.append(m)
else:
cnt += 1
print(cnt)
solution.py