https://www.acmicpc.net/problem/4386
MST 문제에 있어 입력정보에 애초에 간선에 대한 정보와 가중치가 주어진다면 쉽지만
꼭 간선에 대한 정보가 주어지지 않을 수도 있다.
노드에 대한 정보가 주어지고 그 정보를 토대로 간선 후보를 추출해야 한다.
이 문제의 경우 간선 후보가 될 수 있는 최대 경우의 수가 100*100으로 최대 10만번 연산밖에 안되기때문에
간선 후보를 모든 행성이 연결된 것으로 할 수 있다.
먼저 별에대한 입력정보를 받고 별을 n^2 연산으로 간선을 만들고 Kruskal 알고리즘 적용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <iostream> #include <vector> #include <cmath> #include <iomanip> #include <algorithm> using namespace std; int n; class Planet{ public: double x, y; Planet(double x = 0, double y = 0) :x(x), y(y) {} }; class Tunnel{ public: int i; int j; double w; Tunnel(int i = 0, int j = 0, double w = 0) :i(i), j(j), w(w) {} bool operator <(const Tunnel &t) const{ return w < t.w; } }; vector<Tunnel> tunnel; Planet planet[101]; int vRoot[101] = {0, }; double ret = 0; double getDist(Planet p1, Planet p2){ return sqrt(pow(p1.x-p2.x, 2) + pow(p1.y-p2.y, 2)); } int findRoot(int v){ if(vRoot[v] == v) return v; return vRoot[v] = findRoot(vRoot[v]); } void kruskal(){ sort(tunnel.begin(), tunnel.end()); for(Tunnel t : tunnel){ int ri = findRoot(t.i); int rj = findRoot(t.j); if(ri != rj){ // no -cycle merge. vRoot[rj] = ri; ret += t.w; } } cout << setprecision(3) << ret << endl; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; for(int i = 1; i <= n; i++){ int x, y; cin >> planet[i].x >> planet[i].y; vRoot[i] = i; } for(int i = 1; i <= n-1; i++){ for(int j = i+1; j <= n; j++){ //set Tunnels tunnel.push_back(Tunnel(i, j, getDist(planet[i], planet[j]))); } } kruskal(); return 0; } |
'BOJ 문제풀이 > 최소스패닝트리 (MST)' 카테고리의 다른 글
백준 1774 : 우주신과의 교감 (0) | 2018.11.30 |
---|---|
백준 2463 : 비용 (0) | 2018.11.30 |
백준 13418 : 학교 탐방하기 (0) | 2018.11.29 |
백준 1197 : 최소 스패닝 트리 (0) | 2018.11.29 |
백준 16398 : 행성 연결 (0) | 2018.11.29 |