[ BOJ 1325 ] 효율적인 해킹 (파이썬)
백준 온라인 저지: 문제 풀러 가기
1. 문제 요약
알고리즘 분류 | 완전 탐색
해커 김지민은 잘 알려진 어느 회사를 해킹하려고 한다. 이 회사는 N개의 컴퓨터로 이루어져 있다. 김지민은 귀찮기 때문에, 한 번의 해킹으로 여러 개의 컴퓨터를 해킹 할 수 있는 컴퓨터를 해킹하려고 한다.
이 회사의 컴퓨터는 신뢰하는 관계와, 신뢰하지 않는 관계로 이루어져 있는데, A가 B를 신뢰하는 경우에는 B를 해킹하면, A도 해킹할 수 있다는 소리다.
이 회사의 컴퓨터의 신뢰하는 관계가 주어졌을 때, 한 번에 가장 많은 컴퓨터를 해킹할 수 있는 컴퓨터의 번호를 출력하는 프로그램을 작성하시오.
입력 첫째 줄에, N과 M이 들어온다. (N <= 10,000, M <= 100,000)
둘째 줄부터 M개의 줄에 신뢰하는 관계가 A B와 같은 형식으로 들어오며, "A가 B를 신뢰한다"를 의미한다.
컴퓨터는 1번부터 N번까지 번호가 하나씩 매겨져 있다.
출력 첫째 줄에, 김지민이 한 번에 가장 많은 컴퓨터를 해킹할 수 있는 컴퓨터의 번호를 오름차순으로 출력한다.
1줄 요약) 그래프 탐색하자!
2. 접근 방식
-
신뢰하는 관계 => 일방향 간선으로 생각해서 그래프 탐색
- 너비우선(BFS)으로 탐색하면서 방문한 정점의 수를 기록한다.
-
최대치를 찾아야 하므로 모든 경우를 탐색한다.
- 최다 정점을 방문한 시작 정점의 번호를 정답으로 출력한다.
풀이 >
import sys
input = sys.stdin.readline # 중요!!!!, 입력 속도가 느리면 통과 불가능.
from collections import deque
# 너비 우선 탐색
def bfs(s):
D = 0
q = deque()
q.append(s)
visit = [0] * (N + 1)
visit[s] = 1
while q:
here = q.popleft()
D += 1
for w in G[here]:
if not visit[w]:
visit[w] = 1
q.append(w)
return D # 방문한 정점의 수 D를 리턴한다.
N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for i in range(M):
a, b = map(int, input().split())
G[b].append(a)
mxd = 0
result = []
for i in range(1, N + 1):
if G[i]:
tmp = bfs(i) # 리턴값을 받아서 최대값과 비교
if mxd <= tmp:
if mxd < tmp:
result = []
mxd = tmp
result.append(i)
print(*result)
3. 감상
- 시간제한이 빡빡한 문제
import sys;input = sys.stdin.readline
시간 초과시 1순위로 시도해 볼 옵션이다.- 트리/ 그래프 순회문제는 고정된 코드를 쓰는 경우가 많으므로 익숙한 형태로 숙지해놓으면 좋다.
공유하기!