programming/알고리즘 풀이
[백준 알고리즘] 1197번 - 최소 스패닝 트리 (크루스칼 알고리즘)
AGAPE1225
2023. 7. 9. 19:39
반응형
1. 문제 및 예시 실행 결과
solved.ac의 CLASS가 올라갈수록 모르는 알고리즘이 많다. 어제 토스 코테 한번 찍먹하고 많이 반성하게 됐다. 모르는 것을 공부하는게 맞는 것 같다. Union-find를 활용한 크루스칼 알고리즘을 공부하고 적용해보았다. 한큐에 초록 글자가 떠서 너무 좋았다.
출처: https://www.acmicpc.net/problem/1197
1197번: 최소 스패닝 트리
첫째 줄에 정점의 개수 V(1 ≤ V ≤ 10,000)와 간선의 개수 E(1 ≤ E ≤ 100,000)가 주어진다. 다음 E개의 줄에는 각 간선에 대한 정보를 나타내는 세 정수 A, B, C가 주어진다. 이는 A번 정점과 B번 정점이
www.acmicpc.net
2. 풀이과정
문제를 잘게 나눠봤다.
1. 문제 나누기
2. 입력
3. root가 같으면 continue
4. 아니면 정답에 더하고 두 노드 union 처리
다음은 정답 코드이다.
#include <iostream>
#include <vector>
#include <queue>
/*
* 문제 나누기
* 입력
* 찾기
* root 확인
* 아니면 찾기
*/
using namespace std;
priority_queue<pair<int, pair<int, int>>> edges;
int roots[10001];
int get_root(int node) {
if (roots[node] == node) {
return node;
}
else
return roots[node] = get_root(roots[node]);
}
bool find(int node1, int node2) {
int root1 = get_root(node1);
int root2 = get_root(node2);
if (root1 == root2)
return true;
else
return false;
}
void union_node(int node1, int node2) {
int root1 = get_root(node1);
int root2 = get_root(node2);
if (root1 > root2)
roots[root1] = root2;
else
roots[root2] = root1;
}
int main(void) {
int V, E;
int count_node = 1;
int ans = 0;
cin >> V >> E;
for (int i = 0; i <= V; i++) {
roots[i] = i;
}
for (int i = 0; i < E; i++) {
int A, B, C;
cin >> A >> B >> C;
edges.push(make_pair(-C, make_pair(A, B)));
}
if (V == 1) {
cout << 0;
return 0;
}
while (count_node < V) {
//cout << count_node << endl;
int weight = -edges.top().first;
int node1 = edges.top().second.first;
int node2 = edges.top().second.second;
edges.pop();
//만약 두 노드가 연결되어있으면 그냥 진행
if (find(node1, node2)) {
continue;
}
//아니면 ans추가하고 값 연결
ans += weight;
union_node(node1, node2);
count_node++;
}
cout << ans;
return 0;
}
반응형