4386번 : 별자리 만들기
문제 )
도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다.
별자리를 이루는 선은 서로 다른 두 별을 일직선으로 이은 형태이다.
모든 별들은 별자리 위의 선을 통해 서로 직/간접적으로 이어져 있어야 한다.
별들이 2차원 평면 위에 놓여 있다. 선을 하나 이을 때마다 두 별 사이의 거리만큼의 비용이 든다고 할 때, 별자리를 만드는 최소 비용을 구하시오.
입력 :
첫째 줄에 별의 개수 n이 주어진다. (1 ≤ n ≤ 100)
둘째 줄부터 n개의 줄에 걸쳐 각 별의 x, y좌표가 실수 형태로 주어지며, 최대 소수점 둘째자리까지 주어진다. 좌표는 1000을 넘지 않는 양의 실수이다.
출력 :
첫째 줄에 정답을 출력한다. 절대/상대 오차는 10-2까지 허용한다.
풀이)
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
// class를 이용한 간선 관리
class Edge
{
public:
int node[2];
double distance;
Edge(int a, int b, double c)
:node{ a, b }, distance(c)
{}
bool operator < (Edge& edge)
{
return this->distance < edge.distance;
}
};
int par[110];
int rank[110];
vector<vector<double>> temp;
vector<Edge> vec;
int find(int x)
{
if (par[x] == x)
{
return x;
}
else
{ // 경로압축
par[x] = find(par[x]);
return par[x];
}
}
void union_(int a, int b)
{
a = find(a);
b = find(b);
// union by rank
if (::rank[a] < ::rank[b])
{
par[a] = b;
}
else if (::rank[a] > ::rank[b])
{
par[b] = a;
}
else
{
par[a] = b;
::rank[a]++;
}
}
int main()
{
// 입출력 속도 향상
cin.tie(0);
ios_base::sync_with_stdio(false);
// 기본 부모노드 초기화
for (int i = 0; i < 110; i++) par[i] = i;
int n;
cin >> n;
// 좌표 입력 받기
double a, b;
for (int i = 0; i < n; i++)
{
cin >> a >> b;
temp.push_back(vector<double>{a, b});
}
// 입력받은 좌표 활용, 좌표들이 가질 수 있는 모든 거리 계산
// 별의 개수는 100개 이하이므로, 최대 10000개 (시간 제한 여유)
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
a = abs(temp[i][0] - temp[j][0]);
b = abs(temp[i][1] - temp[j][1]);
double dist = pow(pow(a, 2) + pow(b, 2), 0.5);
vec.push_back(Edge(i + 1, j + 1, dist));
}
}
// 최소비용이므로 오름차순으로 정렬
sort(vec.begin(), vec.end());
double cost = 0;
// 최소 비용순서대로 별자리를 이어준다. (크루스칼 알고리즘)
for (auto i = vec.begin(); i < vec.end(); i++)
{
int temp1 = i->node[0];
int temp2 = i->node[1];
if (find(temp1) != find(temp2))
{
union_(temp1, temp2);
cost += i->distance;
}
}
// 소수점 둘째자리까지 출력 고정
cout << fixed;
cout.precision(2);
cout << cost;
return 0;
}
|
cs |
출처 : https://www.acmicpc.net/problem/4386
4386번: 별자리 만들기
도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일
www.acmicpc.net
'Develop > 백준 (Cpp)' 카테고리의 다른 글
[백준] 10988번 : 팰린드롬인지 확인하기 (C++) (0) | 2023.05.03 |
---|---|
[백준] 10808번 : 알파벳 개수 (C++) (0) | 2023.05.03 |
[백준] 1774번 : 우주신과의 교감 (C++) (2) | 2023.04.21 |
[백준] 1647번 : 도시 분할 계획 (C++) (0) | 2023.04.20 |
[백준] 1922번 : 네트워크 연결 (C++) (0) | 2023.04.20 |