import sys import heapq input = sys.stdin.readline N,M,K = map(int,input().split()) graph = [{} for i in range(N+1)] plant = list(map(int,input().split())) INF = float('inf') for _ in range(M): u,v,w = map(int,input().split()) graph[u][v] = min(graph[u].get(v,float('inf')),w) graph[v][u] = min(graph[v].get(u,float('inf')),w) MST_DISTANCE = [INF for i in range(N+1)] visited = [True]*(N+1) result = 0 node_list = [] for start in plant: heapq.heappush(node_list,(0,start)) MST_DISTANCE[start] = 0 while node_list: dis,node = heapq.heappop(node_list) if not visited[node]: continue result += dis visited[node] = False for next_node in graph[node]: if MST_DISTANCE[next_node] >graph[node][next_node]: MST_DISTANCE[next_node] = graph[node][next_node] heapq.heappush(node_list,(MST_DISTANCE[next_node],next_node)) print(result)
서로 다른 발전소끼리 연결이 되면 안되므로, 프림알고리즘을 하는데, 발전소의 위치를 전부 0으로 초기화 해주고,
전부 heapq에 넣어주고, Prim 알고리즘을 돌려주면 된다.
import sys input = sys.stdin.readline def union(a,b): A = find_parent(a) B = find_parent(b) if A != B: if rank[A] < rank[B]: A,B = B,A make_set[B] = A if rank[A] == rank[B]: rank[A] += 1 def find_parent(ind): if make_set[ind] == ind: return ind else: make_set[ind] = find_parent(make_set[ind]) return make_set[ind] N,M,K = map(int,input().split()) plant = list(map(int,input().split())) make_set = [i for i in range(N+1)] rank = [1 for _ in range(N+1)] edges = [] for _ in range(M): u,v,w = map(int,input().split()) edges.append((u,v,w)) edges.sort(key=lambda x : -x[2]) for k in range(1,K): union(plant[k],plant[k-1]) cnt = 1 result = 0 while cnt <(N-K+1): x,y,weight = edges.pop() if find_parent(x) != find_parent(y): union(x,y) result += weight cnt += 1 print(result)
두번째 풀이는 크루스칼을 이용해서 풀었다.
발전소가 서로 연결이 되면 안되므로, 처음부터 모든 발전소를 하나의 union으로 merge를 해준다.
그리고 난뒤에 크루스칼 알고리즘을 해주면 된다.
그리고 전체 간선 수는 전체 노드의 수 - 1 이지만, 여기서는 (N-1)-(K-1)의 수 만큼만 해주면 된다.
이 문제를 처음에 어렵게 생각해서 각 플랜트만의 프림알고리즘을 돌려서, 최저값을 갱신하는 식으로 했다.
하지만, 같이 연결이 안되기만 하면 되니깐 프림 알고리즘을 하면서, 처음 스타트 위치를 전부 넣어주기만 하면 됬다.
이 문제에 더 어울리는 알고리즘은 프림보다, 크루스칼 알고리즘인 것 같다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 5875 오타 (0) | 2021.05.17 |
---|---|
[BOJ/백준] 9944 NxM 보드 완주하기 (0) | 2021.05.17 |
[BOJ/백준] 16939 2x2x2 큐브 (0) | 2021.05.14 |
[BOJ/백준] 15806 영우의 기숙사 청소 (0) | 2021.05.14 |
[BOJ/백준] 14657 준오는 최종인재야! (0) | 2021.05.14 |