import sys
input = sys.stdin.readline
V,E = map(int,input().split())
graph = [{} for _ in range(V+1)]
for _ in range(E):
A,B,C = map(int,input().split())
graph[A][B] = C
graph[B][A] = C
INF = float('inf')
visited = [False]*(V+1)
distance = [INF]*(V+1)
distance[1] = 0
node_list = [(1,0)]
cnt = 1
result = 0
while cnt <V:
node, dis = node_list.pop()
current_min_dis = INF
current_min_node = -1
visited[node] = True
for next_node in graph[node]:
if distance[next_node] > graph[node][next_node]:
distance[next_node] = graph[node][next_node]
for ind in range(1,V+1):
if current_min_dis > distance[ind] and not visited[ind]:
current_min_node = ind
current_min_dis = distance[ind]
node_list.append((current_min_node,current_min_dis))
result += current_min_dis
cnt += 1
print(result)
첫 풀이는 다익스트라랑 비슷한 프림 알고리즘을 이용한 풀이였다. 하지만 해당 풀이는 실행시간이 오래걸려서 또 다른 방식으로 풀었다.
import sys
import heapq
input = sys.stdin.readline
V,E = map(int,input().split())
graph = [{} for _ in range(V+1)]
for _ in range(E):
A,B,C = map(int,input().split())
graph[A][B] = C
graph[B][A] = C
INF = float('inf')
distance = [INF]*(V+1)
visited = [False]*(V+1)
node_list = []
distance[1] = 0
heapq.heappush(node_list,(0,1))
result = 0
while node_list:
key,node = heapq.heappop(node_list)
if visited[node]:
continue
visited[node] = True
result += key
for next_node in graph[node]:
if distance[next_node] > graph[node][next_node]:
heapq.heappush(node_list,(graph[node][next_node],next_node))
distance[node] = graph[node][next_node]
print(result)
두번째는 프림 알고리즘이지만, heapq를 활용한 풀이였다. 위의 방식과 똑같지만, distance가 갱신될때에만을 판단하고, 그때 node_list에 추가하는 방식이었다.
import sys
input = sys.stdin.readline
def union(A,B):
x = find_parent(A)
y = find_parent(B)
if x > y:
x,y = y,x
make_set[y] = x
def find_parent(ind):
if make_set[ind] == ind:
return ind
make_set[ind] = find_parent(make_set[ind])
return make_set[ind]
V,E = map(int,input().split())
grpah = sorted([list(map(int,input().split())) for _ in range(E)],key=lambda x : x[2],reverse=True)
make_set = [i for i in range(V+1)]
cnt = 1
result = 0
while cnt <V:
p1,p2,weight = grpah.pop()
if find_parent(p1) != find_parent(p2):
union(p1,p2)
result += weight
cnt += 1
print(result)
크루스칼 알고리즘으로 푼 방식이다. 크루스칼 알고리즘이 편한사람들은 금방 푼다고하는데, 크루스칼 알고리즘에 익숙하지 못해서 시간이 오래걸렸다.
많이 실패했던것은 make_set에 저장된 parent_node로 비교를 했을때 틀렸다. find_parent 이후에, 루트노드가 바뀐 경우 make_set에 저장된 모든 parent들이 root_node로 갱신되는것이 아니기 때문에, 문제가 생겼었다.
프림 알고리즘과 크루스칼 알고리즘은 자주 쓰이므로 좀 더 익숙해져야겠다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 1261 알고스팟 (0) | 2021.03.08 |
---|---|
[BOJ/백준] 11404 플로이드 (0) | 2021.03.08 |
[BOJ/백준] 1520 내리막길 (0) | 2021.03.04 |
[BOJ/백준] 2580 스도쿠 (0) | 2021.03.02 |
[BOJ/백준] 2206 벽 부수고 이동하기 (0) | 2021.02.28 |