이코테 p397
import sys
input = sys.stdin.readline
# 크루스칼 알고리즘을 활용하면 되겠군, 유니온 파인드 알고리즘을 사용하자
def find(parent, a): # 파인드 (루트 노드를 찾는 함수)
if parent[a] != a:
parent[a] = find(parent, parent[a])
return parent[a]
def union(parent, a, b): # 유니온 (서로 루트노드가 다르면 작은 수쪽으로 합친다)
a = find(parent, a)
b = find(parent, b)
if a < b:
parent[b] = a
else:
parent[a] = b
N, M = map(int, input().split())
parent = list(range(0,N))
edges=[]
result = 0
for _ in range(M):
X,Y,Z = map(int, input().split())
edges.append((Z,X,Y))
result += Z
edges.sort() # O(ELogE)
cnt = 0
for edge in edges:
cost = edge[0]
v1 = edge[1]
v2 = edge[2]
if find(parent, v1) == find(parent, v2): # 사이클이 발생
continue
union(parent, v1, v2)
result -= cost
print(result)
# 크루스칼 알고리즘을 작성해봅시다
# 1. 간선 정렬
# 2. 간선을 하나씩 뽑으면서 사이클이 발생하는지 확인한다.
전형적인 크루스칼 알고리즘 문제였다.
문제조건에서 최대한 !줄일수! 있는 거리를 찾으라고 했는데 최소 거리를 계산해서 디버깅에 애를 먹었다.
문제를 잘읽자.
아 그리고 union 함수를 구현할때 조건절 안의 인수들은 모두 루트노드로 넣어야 제대로 동작한다…!
이것도 디버깅에 애를 먹었다. 기억하도록 하자.
이코테 p398
와 답지봐도 이해가 안됨.. 나중에 이해해 보겠습니다