-
백준 1197 최소 스패닝 트리 - C++, 크루스칼 알고리즘쾌락없는 책임 (공부)/알고리즘 문제풀이 2021. 7. 4. 16:16반응형
#include <iostream> #include <vector> #include <algorithm> using namespace std; int v, e, res = 0, edgenum = 0; pair<int, pair<int , int>> edge[100001]; int parents[10001]; int FindRoot(int x){ if(x == parents[x]) return x; return parents[x] = FindRoot(parents[x]); } void Merge(int x, int y){ x = FindRoot(x); y = FindRoot(y); if(x == y) return; parents[x] = y; } int main(){ scanf("%d %d", &v, &e); for(int i = 0; i <= v; i++) parents[i] = i; for(int i = 0; i < e; i++){ int a, b, c; scanf("%d %d %d", &a, &b, &c); edge[i].first = c; edge[i].second.first = a; edge[i].second.second = b; } sort(edge, edge + e); // 간선 갯수만큼 크루스칼 알고리즘 for(int i = 0; i < e; i++){ if(FindRoot(edge[i].second.first) == FindRoot(edge[i].second.second)) continue; Merge(edge[i].second.first, edge[i].second.second); res += edge[i].first; edgenum++; if(edgenum == v - 1) break; } printf("%d\n", res); }
이전에 Union Find를 공부한 뒤 풀이할려고 둘 문제인데 다른 일을 많이 한다고 알고리즘을 못풀다가 이제야 풀이를 한다. 이전의 Union Find에서 크루스칼 알고리즘을 적용한 것으로 최소 스패닝 트리를 구하기 위해서 간선들을 정렬해준 뒤 작은 것들부터, 부모를 합쳐가면서 최소 스패닝 트리를 만드는데 이때 '부모가 같다 = 사이클이 있다' 이므로 이 경우를 제외하고 크루스칼 알고리즘을 진행하면 답이 나온다.
반응형'쾌락없는 책임 (공부) > 알고리즘 문제풀이' 카테고리의 다른 글
백준 1806 부분합 - C++, 두포인터 (0) 2021.07.22 백준 1461 도서관 - C++, 그리디 알고리즘, 정렬 (0) 2021.07.21 백준 1717 집합의 표현 - C++, Union find (0) 2021.06.29 백준 2660 회장뽑기 - C++, 플로이드-와샬 (0) 2021.06.26 백준 3649 로봇 프로젝트 - C++, 두 포인터, 예외 찾기 (0) 2021.06.26