Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Tags
- 전위순회
- React
- css
- 그래프
- dp
- 너비우선탐색
- Java
- 구현
- js
- Prettier
- MST
- 시뮬레이션
- Java #Backjoon #Algorithm #구현 #시뮬레이션
- webpack
- 최소신장트리
- vscode
- python
- dfs
- 깊이우선탐색
- nodejs
- LIS
- 후위순회
- HTML
- Backjoon
- 최단거리
- algorithm
- eslint
- BFS
- 다이나믹 프로그래밍
- 최장부분증가수열
Archives
- Today
- Total
ULISIA's Developer Life
[Backjoon] 1197 최소 스패닝 트리 Python 문제 풀이 본문
문제해석
최소 신장 트리 (minimum spanning tree)
전체 요소들을 연결할때 사용한다. Kruskal 알고리즘, Prim 알고리즘이 있다.
Kruskal
- 간선들을 정렬
- 간선이 잇는 두 정점의 root를 찾는다.
- 다르다면 하나의 root를 바꾸어 연결 시켜준다.
Prim
- 임의의 정점을 선택
- 해당 정점에서 갈 수 있는 간선을 minheap(최소힙)에 넣는다.
- 최소값을 뽑아 해당 정점을 방문하지 않았다면 선택한다.
Kruskal 알고리즘은 간선들을 정렬해야하기 때문에 간선이 적다면 Kruskal, 많다면 Prim을 선택한다.
비슷한 알고리즘으로 다익스트라 알고리즘이 있다.
다익스트라는 전체 요소를 연결하는 것이 아닌 한 정점에서 다른 정점으로 가는 가장 짧은 방법을 구할 때 사용한다.
다익스트라
- 최단 거리 배열을 무한대로 초기화한다. 방문여부 배열은 False로 초기화 한다.
- 출발 노드는 방문했다고 체크 후 heap에 넣는다.
- 아직 방문하지 않은 노드들 중, 최단 거리 테이블 값이 가장 작은 노드를 선택한다.
- 저장된 최단거리 값과 현재노드에 가중치를 더한 거리 값 중 더 작은 값으로 update한다.
해답코드
1. Kruskal
- root를 저장하는 vRoot 배열 생성. (여기서 root는 연결요소 중 가장 작은 값, 처음에는 자기 자신을 저장)
- 간선들(eList)를 가중치(gain) 기준으로 정렬.
- 간선들이 이은 두 정점을 find 함수를 통해 두 root(sRoot, eRoot)를 찾는다.
- 두 root가 다르다면 큰 root값을 작은 root값으로 만들어 연결되게 해준다.
- 가중치를 더한다.
# 최소 스패닝 트리
#1. Kruskal
import sys
input = sys.stdin.readline
v, e = map(int, input().split())
vRoot = [i for i in range(v+1)]
eList = []
for _ in range(e):
eList.append(list(map(int,input().split())))
eList.sort(key=lambda x: x[2])
def find(x):
if x != vRoot[x]:
vRoot[x] = find(vRoot[x])
return vRoot[x]
ans=0
for start, end, gain in eList:
startRoot = find(start)
endRoot = find(end)
if startRoot != endRoot:
if startRoot>endRoot:
vRoot[startRoot] = endRoot
else:
vRoot[endRoot] = startRoot
ans += gain
print(ans)2. Prim
- isVisited : 방문여부 확인
- eList : 간선 저장
- heap : 현재 그래프에서 짧은 경로를 선택
- 현재 그래프에서 가장 짧은 간선을 골라 방문하지 않은 정점이라면 선택한다.
#2. Prim
import sys
import heapq
input = sys.stdin.readline
v, e = map(int, input().split())
isVisited = [False]*(v+1)
eList = [[] for _ in range(v+1)]
heap = [[0, 1]]
for _ in range(e):
start, end, gain = map(int, input().split())
eList[start].append([gain,end])
eList[end].append([gain,start])
ans = 0
cnt = 0
while heap:
if cnt == v:
break
gain, start = heapq.heappop(heap)
if not isVisited[start]:
isVisited[start] = True
ans += gain
cnt += 1
for i in eList[start]:
heapq.heappush(heap, i)
print(ans)'Algorithm > Backjoon' 카테고리의 다른 글
| [Backjoon] 5639 이진 검색 트리 Python 문제 풀이 (0) | 2023.07.21 |
|---|---|
| [Backjoon] 1916 최소비용 구하기 Python 문제 풀이 (0) | 2023.07.19 |
| [Backjoon] 24479 알고리즘 수업 - 깊이 우선 탐색 1 Python 문제 풀이 (0) | 2023.07.17 |
| [Backjoon] 5567 결혼식 Python 문제 풀이 (0) | 2023.07.16 |
| [Backjoon] 14002 가장 긴 증가하는 부분 수열 4 Python 문제 풀이 (0) | 2023.07.15 |
