읽기 전
- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
- 개인적으로 배운 점을 정리한 글입니다.
문제 링크
문제 풀이
최소신장트리로 가볍게 풀려다가 시간 초과에 메모리 초과까지 당했다. 기존 스패닝 트리 문제에서는 노드에 초점을 맞췄다면 이 문제는 총 비용만 계산하면 되므로 x, y, z에 대해 각각의 거리를 계산한다. 그리고 최소 비용이므로 굳이 다른 노드들끼리는 필요 없고 거리 순으로 정렬한 뒤 인접한 원소의 거리만 계산하면 된다.
- 유니온-파인드 알고리즘 함수를 정의해둔다.
- x, y, z를 별도의 세 배열에 저장하고 튜플 형식으로 좌표만 넣어 어디 행성의 것인지만 표기한다.
- 간선을 관리하는 배열을 선언한 뒤 정렬된 x, y, z 좌표 배열의 인접 원소끼리의 거리를 구해 해당 좌표들에 대한 정보를 담아 간선 배열에 넣는다.
- 간선 배열을 정렬하고 큐로 변환한다.
- 간선의 개수가 N - 1개가 될 때까지 유니온-파인드 알고리즘을 수행한다. 유효한 간선일 경우 간선의 개수에 1을 더해준다.
python 코드
import sys
from collections import deque
input = sys.stdin.readline
def solve():
def upward(buf, idx):
parent = nodes[idx]
if parent < 0:
return idx
buf.append(idx)
return upward(buf, parent)
def find(idx):
buf = []
result = upward(buf, idx)
for b in buf:
nodes[b] = idx
return result
def union(x, y):
x, y = find(x), find(y)
if x == y:
return False
if nodes[x] < nodes[y]:
nodes[y] = x
elif nodes[x] > nodes[y]:
nodes[x] = y
else:
nodes[x] -= 1
nodes[y] = x
return True
N = int(input())
x, y, z = [], [], []
for i in range(N):
a, b, c = map(int, input().split())
x.append((a, i))
y.append((b, i))
z.append((c. i))
x.sort()
y.sort()
z.sort()
r = []
for i in range(1, N):
r.append(x[i][0] - x[i - 1][0], x[i - 1][1], x[i][1])
r.append(y[i][0] - y[i - 1][0], y[i - 1][1], y[i][1])
r.append(z[i][0] - z[i - 1][0], z[i - 1][1], z[i][1])
r.sort()
r = deque(r)
cnt = 0
sol = 0
nodes = [-1 for _ in range(N)]
while True:
dist, i, j = r.popleft()
if union(i, j) is True:
cnt += 1
sol += dist
if cnt == N - 1:
break
return sol
print(solve())
'Algorithms > Baekjoon' 카테고리의 다른 글
BOJ #9345 디지털 비디오 디스크(DVDs) (0) | 2021.08.16 |
---|---|
BOJ #2437 저울 (0) | 2021.08.12 |
BOJ #1202 보석 도둑 (0) | 2021.08.12 |
BOJ #1107 리모컨 (0) | 2021.08.10 |
BOJ #11051 이항 계수 2 (0) | 2021.08.10 |