====== 우주신과의 교감 ====== ===== 풀이 ===== * 유클리디안 [[ps:최소 신장 트리]]의 변형. 유클리디안 최소 신장 트리는, 들로네 삼각분할을 이용한 고급 알고리즘을 사용하지 않는 범위에서는, 그냥 완전 그래프를 만들고서 거기에서 MST를 찾는 방식으로 구하게 된다 ([[ps:problems:boj:4386]] 참고). 여기에서는 이때 미리 주어진 엣지들을 먼저 포함 시킨다음에 이어서 MST를 찾도록 알고리즘을 살짝 바꾸면 된다. * 크루스칼 알고리즘을 쓸 경우는 간단하게 바꿀수 있다. 먼저 미리 주어진 엣지들을 union 해놓고서, 나머지 엣지들을 대상으로 알고리즘을 계속 돌리면 된다. 프림으로 할 경우에는 mst에 포함된 노드들을 하나 추가할때마다, 그 노드들과 미리 연결되어있던 노드들을 찾아서 함께 추가하는 식으로 고쳐야 한다. * 하지만 더 간단하게, 그냥 기존 알고리즘 코드를 그냥 그대로 쓸 수 있는 방법도 있다. 미리 연결된 점들을 가중치를 0인 엣지로 취급해서 원래 그래프에 추가해주고 그대로 돌리면 된다. 이렇게 그래프를 만들면 프림이나 크루스칼이나 모두 원하는대로 동작한다. 완전그래프라서 O(n^2)의 프림 알고리즘이 O(n^2logn)의 크루스칼 알고리즘보다 빠르게 동작한다 ===== 코드 ===== """Solution code for "BOJ 1774. 우주신과의 교감". - Problem link: https://www.acmicpc.net/problem/1774 - Solution link: http://www.teferi.net/ps/problems/boj/1774 Tags: [Minimum spanning tree] """ import math import sys from teflib import graph as tgraph def main(): N, M = [int(x) for x in sys.stdin.readline().split()] coords = [[int(x) for x in sys.stdin.readline().split()] for _ in range(N)] edges = set() for _ in range(M): u, v = [int(x) for x in sys.stdin.readline().split()] edges.add((u - 1, v - 1)) edges.add((v - 1, u - 1)) mat_graph = tgraph.create_mat_graph( N, lambda u, v: (0 if (u, v) in edges else math.dist(coords[u], coords[v]))) mst_edges = tgraph.minimum_spanning_tree_dense(mat_graph) answer = sum(w for u, v, w in mst_edges) print(f'{answer:.2f}') if __name__ == '__main__': main() * Dependency: * [[:ps:teflib:graph#minimum_spanning_tree_dense|teflib.graph.minimum_spanning_tree_dense]] * [[:ps:teflib:graph#create_mat_graph|teflib.graph.create_mat_graph]] {{tag>BOJ ps:problems:boj:골드_4}}