출처 : https://www.acmicpc.net/problem/13418
풀이 방법
union-find알고리즘을 통해 해결할 수 있다.
기존의 알고리즘과 다른 점은 0에서 1로 가는 간선은 무조건 포함되어야 한다는 점이다.
또 가장 힘든 경우와 가장 덜 힘든 경우를 계산하기 위해 mst알고리즘을 2번 사용했다.
주의: mst알고리즘을 사용하기 전 parents를 초기화해주어야 한다.
N, M = map(int, input().split())
edges = []
parents = [ i for i in range(N+1)]
a, b, c = map(int, input().split()) ## 0~1 엣지 무조건 추가되어야 할 edge
first_weight = 1 - c ## 첫 번째 edge의 weight 오르막인지 내리막인지
for i in range(M): ## 엣지 추가
a, b, c = map(int, input().split())
edges.append([a, b, c])
def union(a, b): ## union 알고리즘
a = find(a)
b = find(b)
if a < b:
parents[b] = a
else:
parents[a] = b
def find(a): ## find알고리즘
if parents[a] == a:
return a
parents[a] = find(parents[a])
return parents[a]
def mst():
cnt = 0 ## 0~1엣지 포함
weight = first_weight ## 0~1 edge는 무조건 포함
for i in range(M):
if cnt == N-1: ## 모든 엣지를 포함하면 break
break
a, b, c = edges[i]
if find(a) != find(b):
union(a, b)
cnt += 1 ## 카운드 + 1
if c == 0: ## 오르막인 경우
weight += 1 ## weight 1추가
return weight ** 2 ## weight 제곱
## 내리 막 위주로 되게 정렬 0이 오르막 1이 내리막
## 가장 비용이 작은 경우
edges.sort(key = lambda x : -x[2])
first = mst()
## 가장 비용이 큰 경우
## 부모 초기화
parents = [ i for i in range(N+1)]
edges.sort(key = lambda x : x[2])
second = mst()
print(second - first)
'Algorithm' 카테고리의 다른 글
[백준] 줄 세우기 2252 (python) 위상정렬 (0) | 2024.07.28 |
---|---|
[백준] 전깃줄 2565번 (python) LSB (1) | 2024.07.20 |
[백준] 최소 스패닝 트리 (python) (1) | 2024.07.14 |
[백준] 바이러스 공격 31791번 우선순위 큐 (python) (0) | 2024.06.03 |
[백준] 집합의 표현(유니온 파인드) 1717번 (python) (0) | 2024.05.25 |