반응형

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

 

1774번: 우주신과의 교감

(1,1) (3,1) (2,3) (4,3) 이렇게 우주신들과 황선자씨의 좌표가 주어졌고 1번하고 4번이 연결되어 있다. 그렇다면 1번하고 2번을 잇는 통로를 만들고 3번하고 4번을 잇는 통로를 만들면 신들과 선자씨끼

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 각 좌표를 입력받고 모든 좌표 간의 거리를 pq에 넣습니다. 이때, 점 사이 거리를 제곱한 값이 int를 벗어나므로 long long형으로 제곱해줍니다.

 

2. Union Find를 통해 입력 받은 신들끼리 부모를 연결해줍니다.

 

3. pq에서 하나씩 뽑으면서 a와 b 점의 부모가 같지 않다면 Union 해주시고, dist를 ans에 더해줍니다.

 

4. ans를 출력합니다.

 

[ 소스코드 ]

 

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
#include<iostream>
#include<queue>
#include<cmath>
#define ll long long
 
using namespace std;
 
struct node {
    int from;
    int to;
    double dist;
};
 
struct cmp {
    bool operator()(node right, node left) {
        return left.dist < right.dist;
    }
};
 
int N, M;
pair<intint> arr[1001];
int vect[1001];
priority_queue<node, vector<node>, cmp> pq;
 
int Find(int a)        //부모 찾기
{
    if (vect[a] == a) return a;
    return vect[a] = Find(vect[a]);
}
 
void Union(int a, int b)    //부모 합치기
{
    int pa = Find(a);
    int pb = Find(b);
 
    vect[pb] = pa;
}
 
int main()
{
    scanf("%d %d"&N, &M);
 
    for (int i = 1; i <= N; i++) {
        vect[i] = i;
    }
 
    for (int i = 1; i <= N; i++) {
        scanf("%d %d"&arr[i].first, &arr[i].second);
    }
 
    for (int i = 1; i <= N - 1; i++) {        //모든 점 간의 거리를 기준으로 pq에 넣기
        for (int j = i+1; j <= N; j++) {
            ll x1 = arr[i].first;
            ll x2 = arr[j].first;
            ll y1 = arr[i].second;
            ll y2 = arr[j].second;
            double dist = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
            pq.push({ i,j,dist });
        }
    }
 
    for (int i = 0; i < M; i++) {
        int a, b;
        scanf("%d %d"&a, &b);
        
        if (Find(a) != Find(b)) {
            Union(a, b);
        }
    }
 
    double ans = 0;
 
    while (!pq.empty()) {
        int a = pq.top().from;
        int b = pq.top().to;
        double dist = pq.top().dist;
        pq.pop();
 
        if (Find(a) != Find(b)) {
            Union(a, b);
            ans += dist;
        }
    }
 
    printf("%.2f", ans);
}
cs
반응형

+ Recent posts