DAMPER's blog

4386. 별자리 만들기 본문

Problem Solving/BOJ 문제풀이

4386. 별자리 만들기

DAMPER 2022. 1. 3. 22:17
728x90

https://www.acmicpc.net/problem/4386

 

4386번: 별자리 만들기

도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일

www.acmicpc.net

 

문제 설명

N개의 별에 대한 (x, y) 좌표가 있다. 이 별들을 직선으로 이어 별자리를 만든다고 한다.

별자리를 만들 때는 다음 조건을 따른다. 

  • 별자리를 이루는 선은 서로 다른 두 별을 일직선으로 이은 형태이다.
  • 모든 별들은 별자리 위의 선을 통해 서로 직/간접적으로 이어져 있어야 한다

선을 하나 이을 때마다 두 별 사이의 거리만큼의 비용이 든다고 할 때, 별자리를 만드는 최소 비용을 구하시오.

 

비용은 두 별 사이의 거리이고, 모든 별들을 선을 통해 하나로 만든다는 내용으로 보면 별이 node인 MST를 구성하라는 문제이다.

 

별이 node라면 간선은 두 별 사이에 선을 뜻한다.

모든 간선을 구하는 것은 모든 별에 대해 어떤 별과 다른 모든 별의 거리를 모두 구해 총 \( \frac{N(N+1)}{2} \) 개의 간선을 구축하면 된다.

 

MST 최소 비용은 크루스칼 알고리즘 또는 프림 알고리즘을 사용하여 구할 수 있다.

 

 

크루스칼 알고리즘을 사용한 방법으로 해결한 코드이다.

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
73
74
75
76
77
78
79
80
#include <bits/stdc++.h>
 
using namespace std;
 
#define swap(a,b) (a)^=(b)^=(a)^=(b)
#define endl '\n'
#define int long long
 
using pii = pair<intint>;
 
const double EPS = 1e-9;
const int dx[] = {1-100};
const int dy[] = {001-1};
 
double getDistance(pair<doubledouble> a, pair<doubledouble> b)
{
    return pow((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second), 0.5);
}
 
#define SIZE 101
class Disjoint_Set
{
public:
    int parent[SIZE+1];
    Disjoint_Set()
    {
        for(int i=1;i<=SIZE;i++)
            parent[i] = i;
    }
    int find(int v)
    {
        if(parent[v] == v) return v;
        return parent[v] = find(parent[v]);
    }
    bool merge(int u, int v)
    {
        u = find(u);
        v = find(v);
        if(u == v) return false;
        parent[u] = v;
        return true;
    }
};
 
Disjoint_Set DS;
 
int32_t main()
{
    cin.sync_with_stdio(NULL);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int n;
    cin >> n;
    vector<pair<doubledouble>> points(n+1);
    for(int i=1;i<=n;i++)
    {
        cin >> points[i].first >> points[i].second;
    }
    vector<pair<double, pii>> dists;
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            dists.push_back({getDistance(points[i], points[j]), {i, j}});
        }
    }
    sort(dists.begin(), dists.end());
    double ans = 0.0;
    for(size_t i=0;i<dists.size();i++)
    {
        if(DS.merge(dists[i].second.first, dists[i].second.second))
        {
            ans += dists[i].first;
        }
    }
    cout << ans;
 
    return 0;
}
cs

 

 

 

 

728x90

'Problem Solving > BOJ 문제풀이' 카테고리의 다른 글

9527. 1의 개수 세기  (0) 2022.01.05
2342. Dance Dance Revolution  (0) 2022.01.04
17425. 약수의 합  (0) 2022.01.01
14003 가장 긴 증가하는 부분 수열 5  (0) 2021.08.28
1208 부분수열의 합 2  (0) 2021.08.20