수타. 2023. 6. 9. 10:19

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

 

2887번: 행성 터널

첫째 줄에 행성의 개수 N이 주어진다. (1 ≤ N ≤ 100,000) 다음 N개 줄에는 각 행성의 x, y, z좌표가 주어진다. 좌표는 -109보다 크거나 같고, 109보다 작거나 같은 정수이다. 한 위치에 행성이 두 개 이

www.acmicpc.net

문제요약;

행성의 x,y,z좌표가 주어지고 각 행성간 거리는 서로의 좌표의 차이중 가장 짧은 것을 기준으로 한다.

모든 행성을 연결할 가장 짧은 엣지 합은?

플레5

 

소요시간:

30분

 

1차 시도:

import sys
input = sys.stdin.readline

n = int(input())
arr = []
for i in range(n):
	x,y,z = map(int,input().split())
	arr.append((x,y,z,i))

#모든행성을 터널로 연갈하는 데 최소비용? > 크루스칼 사용
parent = [i for i in range(n+1)]

#크루스칼
def find(parent,x):
	if parent[x] !=x:
		parent[x] = find(parent,parent[x])
	return parent[x]

def union(parent,x,y):
	y = find(parent,y)
	x = find(parent,x)

	if y>x:
		parent[y] =x
	else:
		parent[x] =y

#크루스칼을 하되, 전체 다 할 수 없으므로, x,y,z기준으로 sorted한후 바로 앞뒤(제일짧은)사이 거리넣기
dist = []
ans = 0
for i in range(3):
	arr.sort(key = lambda x : x[i])
	for j in range(n-1):
		dist.append((arr[j+1][i]-arr[j][i],arr[j+1][3],arr[j][3]))

dist.sort()
num = 0
#그후 크루스칼 이때 다 연결 했다면 미리 나오기
for l,j,i in dist:
	if find(parent,j) != find(parent,i):
		union(parent,j,i)
		ans +=l
		num +=1
		if num == n-1:
			break
print(ans)