[파이썬] 백준 1774번 우주신과의 교감
작성:
백준 #1774 우주신과의 교감
# 2차원
# 모든 우주신을 연결해야한다
# 이미 연결된 통로 외에 새로 만들어야 할 통로 길이 합이 최소가 되어야 한다.
# 거리: 2차원 좌표상의 거리
# 출력: 만들어야할 최소 통로 길이
# 이미 있는 통로를 포함하는 최소 스패닝 트리의 크기를 구한다.
# 새로 만들어지는 통로의 길이만 고려한다.
# 크루스칼 알고리즘을 사용한다.
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):
xroot = find(x, parents)
yroot = find(y, parents)
if ranks[xroot] >= ranks[yroot]:
parents[yroot] = xroot
else:
parents[xroot] = yroot
if ranks[xroot] == ranks[yroot]:
ranks[xroot] += 1
def kruskal(edges, parents, ranks, cnt):
cost = 0
for val, s, e in edges:
if find(s, parents) != find(e, parents):
cost += val
union(s, e, parents, ranks)
cnt += 1
if cnt == len(parents)- 1: return cost
return cost
def solution(N, M):
edges = []
x, y = map(int, input().split())
parents = [i for i in range(N+1)]
ranks = [0 for i in range(N+1)]
coors = [None, (x, y)]
head = 2
for i in range(N-1):
x1, y1 = map(int, input().split())
for j in range(1, len(coors)):
x2, y2 = coors[j]
d = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** (1/2)
edges.append((d, j, head))
coors.append((x1, y1))
head += 1
cnt = 1
for i in range(M):
a, b = map(int, input().split())
if find(a, parents) != find(b, parents):
union(a, b, parents, ranks)
cnt += 1
edges.sort()
print('{0:0.2f}'.format(kruskal(edges, parents, ranks, cnt)))
if __name__ == '__main__':
solution(*map(int, input().split()))
댓글남기기