https://www.acmicpc.net/problem/1922
이번 문제도 그래프를 이용해 최소 신장 트리를 만드는 문제이다 단 저번 게시물에는 크루스칼 알고리즘을 이용 하였으나 이번 알고리즘은 프림 알고리즘을 이용해서 풀었다.
프림 알고리즘은 현재 나와 연결된 노드들을 점점확장하면서 최소 신장 트리를 만드는 것이다
프림 알고리즘은 크루스칼알고리즘과 다르게 간선들이 많을 때 효율적이다.
프림알고리즘의 로직은 대충 일단 내가 갈수 있는 곳중 가까운 곳을 연결한다. 그리고 내가 갈수 있는 곳과 그 갈수 있는 버텍스를 통해서 갈수 있는 곳중 가장 비용이 낮은 곳으로 간다
위의 과정을 vertex의 갯수-1 만큼 반복해주면 된다.
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int parent[1001];
vector<priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>> inputData(1001);
int findParent(int x) {
if (parent[x] == x)
return x;
else return parent[x] = findParent(parent[x]);
}
bool isSameParent(int x, int y) {
int parentOfX = findParent(x);
int parentOfY = findParent(y);
if (parentOfX == parentOfY) {
return true;
}
else {
return false;
}
}
void uni(int x, int y) {
x = findParent(x);
y = findParent(y);
parent[y] = x;
}
int main() {
int n, m;
cin >> n;
cin >> m;
int com1 = 0, com2 = 0, cost = 0,result=0;
for (int i = 0; i < m; i++) {
int from, to, cost;
cin >> from >> to >> cost;
inputData[from].push({ cost,to });
inputData[to].push({ cost,from });
}
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
for (int i = 1; i < n ; i++) {
while (!inputData[1].empty()) {
com1 = 1;
com2 = inputData[1].top().second;
cost = inputData[1].top().first;
inputData[1].pop();
if (!isSameParent(com1, com2)) {
result += cost;
uni(com1, com2);
while (!inputData[com2].empty()) {
inputData[com1].push(inputData[com2].top());
inputData[com2].pop();
}
break;
}
}
}
cout << result;
}
'백준(코테준비) > 그래프' 카테고리의 다른 글
백준 2887 / C++ / 그래프 / 크루스 (0) | 2025.01.12 |
---|---|
백준 2252 / CPP / 위상 정렬 (1) | 2024.12.01 |
백준 4386 / C++ (0) | 2024.08.04 |
백준 1647 / C++ (0) | 2024.08.04 |
백준 1197 (0) | 2024.07.27 |