prim과 kruskal 둘 다 MST라서 구하고자하는 것은 같다. 하지만,
kruskal : 간선 정렬, Union & Find 활용
prim : 인접리스트, priority queue활용
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int ch[30];
struct Edge{
int e;
int val;
Edge(int a, int b){
e = a;
val = b;
}
bool operator<(const Edge &ref)const{
//priority_queue에서 동작
//최소힙을 만들어줌.
return val > ref.val;
}
};
int main() {
priority_queue<Edge> Q;
vector<pair<int, int>> map[30]; //인접리스트
int i,n,m,a,b,c,res=0;
scanf("%d %d",&n,&m);
for(i = 1; i <= m; i++){
scanf("%d %d %d",&a,&b,&c);
map[a].push_back(make_pair(b, c));
map[b].push_back(make_pair(a, c));//양방향 가중치 그래프 인접리스트
}//문제에서 주어준 그래프 그리기
Q.push(Edge(1,0));//노드 1에서 시작한다.
while (!Q.empty()) {
Edge tmp = Q.top(); //top 데이터 가져오고
Q.pop();//바로 pop
int v= tmp.e;//top데이터 노드번호 참조
int cost = tmp.val;//top데이터 비용 참조
if(ch[v] == 0){ //방문하지 않았다면
res += cost;//코스트 누적
ch[v] = 1;//방문했다.
for(i = 0; i < map[v].size(); i++){//인접리스트와 연결된 노드 모두 참조
Q.push(Edge(map[v][i].first, map[v][i].second));//Q에 담는다.
}
}
}
printf("%d\n",res);
return 0;
}
- kruskal은 구조체형 1.vector에 노드와 간선 정보를 저장해놓고, 2.정렬한 후, 3.Union & Find로 연결하였다.
- Prim은 1.인접리스트로 미리 연결을 해놓고, 2.출발 노드를 priority queue로 지정해놓고 노드와 연결된 3.인접리스트를 탐색하면서 priority queue에 push한다.
- kruskal 구조체에는 v1, v2 ,val정보를 저장하고 vector를 활용했으나
- Prim은 인접리스트를 이용하였으므로 구조체에는 출발노드 e와 val만 저장한다.
- pirority queue에는 cost가 작은 것부터 오름차순으로 정렬되므로 비용이 작은 노드부터 탐색해나간다.
- 또한 이미 방문한 노드는 체크를 하기 때문에 Cycle이 발생하지 않는다.
https://www.inflearn.com/course/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98/dashboard
'기타등등 > 알고리즘 기록' 카테고리의 다른 글
[C++] 벨만포드 알고리즘 - 기초 (0) | 2021.08.10 |
---|---|
[C++] 다익스트라 알고리즘(Greedy, priority queue활용) - 기초 (0) | 2021.08.08 |
[C++] Kruskal MST 알고리즘(Greedy, Union & Find 활용) - 원더랜드 (0) | 2021.08.06 |
[C++] Union&Find 자료구조 - 친구인가? (0) | 2021.08.06 |
[C++] 이항계수(메모이제이션) (0) | 2021.08.06 |