728x90
🔗 문제 링크
https://www.acmicpc.net/problem/1197
💡 문제 풀이 및 해석
- 문제에서 최소 스패닝 트리라고 나와 있으므로 같은 방식으로 풀면 좋다.
- 사실 최소 스패닝 트리가 기억이 잘 나지 않지만, 일단 트리 형식을 갖추면서 가중치가 가장 적은 트리를 만들어야 한다는 것을 알 수 있다.
- 그러면 최대한 낮은 비용의 간선부터 연결해야 한다.
- 단, 간선을 연결할 때, Cycle이 생기면 안된다. => Root가 같은 것들끼리는 연결해서는 안된다.
- 따라서 비용을 오름차순으로 정렬하고 4번을 지키면서 낮은 것들을 계속 연결해가면 된다.
- 단, 매번 부모를 계속 찾을 수 없으므로 매번 현재 나의 Root가 무엇인지 업데이트 해준다.
⭐️ 정답 코드 및 설명
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int V, E;
vector<pair<int, pair<int, int>>> edges; // cost, V1, V2
int root[10001];
void input() {
cin >> V >> E;
// 일단, 처음엔 모두 자기 자신이 Root다.
for (int i = 1; i <= V; i++) {
root[i] = i;
}
for (int i = 0; i < E; i++) {
int A, B, C;
cin >> A >> B >> C;
edges.push_back({C, {A, B}});
}
// 비용 기준으로 오름차순
sort(edges.begin(), edges.end());
}
// 부모를 찾는 메서드
int getRoot(int x) {
if (root[x] == x) return x;
return root[x] = getRoot(root[x]); // 매번 업데이트
}
long long sol() {
int cost, A, B;
long sum = 0;
for (auto edge : edges) {
cost = edge.first;
A = edge.second.first;
B = edge.second.second;
if (getRoot(A) != getRoot(B)) { // 부모가 다르다면
sum += cost;
root[getRoot(B)] = getRoot(A); // 부모를 업데이트해준다.
}
}
return sum;
}
int main() {
input();
cout << sol();
return 0;
}
🤔 문제 후기
root[getRoot(B)] = getRoot(A);
이 부분에서 root[B] = getRoot(A);
로 풀어서 너무 오래 걸렸다. 다른 부분은 10~20분 만에 작성하였는데, 해당 부분을 고치는데 1시간이 걸린 것 같다. 처음에는 당연히 B가 A의 루트로 업데이트 되니 문제 없을 것이라고 생각했지만, https://www.acmicpc.net/board/view/139913 이곳의 반례를 보고 B의 루트를 바꿔줘야 하는 것을 알았다. 그래야 나중에 1->2->6->4->8 이런식으로 나왔을 때, 3->7->8 으로 연결하고 1->3 으로 연결할 때, 문제가 생기지 않는다.(루트는 1이다.) 설명을 잘 못한 것 같은데, 해당 반례를 보고 node의 좌표를 찍어보면 이해하면 할 수 있을 것이다.
728x90
'알고리즘 문제 풀이' 카테고리의 다른 글
[ 백준 16236 ] 아기 상어 (C++) - BFS (1) | 2024.09.11 |
---|---|
[ 백준 1083 ] 소트 (C++) - 그리디 (4) | 2024.09.07 |
[ 백준 1253 ] 좋다 (C++) - 투 포인터 (0) | 2024.09.05 |
[ 백준 1106 ] 호텔 (C++) - 냅색, DP (1) | 2024.09.05 |
[ 백준 1327 ] 소트 게임 (C++) - BFS (3) | 2024.09.04 |