ps:problems:boj:1774
우주신과의 교감
ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 1774 |
문제명 | 우주신과의 교감 |
레벨 | 골드 4 |
분류 |
최소 신장 트리 |
시간복잡도 | O(n^2) |
인풋사이즈 | n<=1000 |
사용한 언어 | Python |
제출기록 | 32952KB / 388ms |
최고기록 | 388ms |
해결날짜 | 2022/10/04 |
태그 |
풀이
- 유클리디안 최소 신장 트리 (Minimum Spanning Tree / MST)의 변형. 유클리디안 최소 신장 트리는, 들로네 삼각분할을 이용한 고급 알고리즘을 사용하지 않는 범위에서는, 그냥 완전 그래프를 만들고서 거기에서 MST를 찾는 방식으로 구하게 된다 (별자리 만들기 참고). 여기에서는 이때 미리 주어진 엣지들을 먼저 포함 시킨다음에 이어서 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/problems/boj/1774.txt · 마지막으로 수정됨: 2022/10/07 17:38 저자 teferi
토론