[파이썬] 백준 2887번 행성 터널
작성:
백준 #2887 행성 터널
# N개의 행성
# 터널 연결비용 min(|xa - xb|, |ya - yb|, |za - zb|)
# 터널 N-1개
# 출력: 모든 행성을 터널로 연결하는데 필요한 최소 비용
# 체크할 조건
# N <= 100000
# 간선을 있는 대로 다 만들면 시간초과
# 크루스칼 알고리즘
# x, y, z 모두 각각 정렬한 후
# 10만개의 좌표에 대해서 인접한 점만 검사해서 edge에 넣는다.
import sys
input = sys.stdin.readline
def find(x, parents):
if parents[x] == x: return x
parents[x] = find(parents[x], parents)
return parents[x]
def union(x, y, parents, ranks):
xr = find(x, parents)
yr = find(y, parents)
if ranks[xr] >= ranks[yr]:
parents[yr] = xr
else:
parents[xr] = yr
if ranks[xr] == ranks[yr]:
ranks[xr] += 1
def kruskal(edges, parents, ranks, cnt):
cost = 0
for val, x, y in edges:
if not cnt: return cost
if find(x, parents) != find(y, parents):
union(x, y, parents, ranks)
cnt -= 1
cost += val
return cost
def solution(N):
parents = [i for i in range(N)]
ranks = [0 for i in range(N)]
planets = []
edges = []
for i in range(N):
x, y, z = map(int, input().split())
planets.append([x, y, z, i])
cnt = N-1
for i in range(3):
planets.sort(key=lambda x: x[i])
for j in range(1, N):
nowv, nowi = planets[j][i], planets[j][3]
prevv, previ = planets[j-1][i], planets[j-1][3]
edges.append([abs(nowv - prevv), nowi, previ])
edges.sort()
print(kruskal(edges, parents, ranks, cnt))
if __name__ == '__main__':
solution(int(input()))
댓글남기기