[백준 1774번] 우주신과의 교감

2023. 9. 10. 03:25·알고리즘 문제풀이/백준
반응형

문제 링크: 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. 이미 연결된 통로를 입력받을 때, 중복된 간선이 들어올 수 있습니다.

 

예를 들어, 1-2와 2-1은 동일한 간선을 나타냅니다. 이 경우를 고려하지 않으면 현재까지 최소 스패닝 트리에 추가된 간선의 수를 계산할 때 문제가 생길 수 있습니다.

 

2. 좌표 값의 최댓값이 10^6이므로, 거리를 계산할 때 오버플로우를 방지하기 위해 long long 자료형을 사용해야 합니다.

 

<C++소스코드>

 
#include<iostream>
#include<utility>
#include<algorithm>
#include<vector>
#include<tuple>
#include<cmath>
using namespace std;

typedef long long ll;

int n, m;
pair<ll, ll> arr[1001];
int parents[1001];
vector<tuple<double, ll, ll> > edge;

int Find(int x) {
    if (parents[x] == x) return x;
    return parents[x] = Find(parents[x]);
}

void Union(int x, int y) {
    int xParents = Find(x);
    int yParents = Find(y);
    if (xParents < yParents) parents[xParents] = yParents;
    else parents[yParents] = xParents;
}


int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    cin >> n >> m;
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        parents[i] = i;
    }
    for (int i = 1; i <= n; i++) {
        int x, y; cin >> x >> y;
        arr[i] = { x, y };
    }
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        if (Find(u) == Find(v)) continue;
        cnt++;
        Union(u, v);
    }
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            if (Find(i) == Find(j)) continue;
            double dist = sqrt((arr[i].first - arr[j].first) * (arr[i].first - arr[j].first) + (arr[i].second - arr[j].second) * (arr[i].second - arr[j].second));
            edge.push_back({ dist, i, j });
        }
    }
    sort(edge.begin(), edge.end());
   
    double ans  = 0;
    for (auto& e : edge) {
        double dist;
        int u, v;
        tie(dist, u, v) = e;
        if (Find(u) == Find(v))continue;
        Union(u, v);
        cnt++;
        ans += dist;
        if (cnt == n - 1) break;
    }
    cout << fixed;
    cout.precision(2);
    
    cout << ans;

    return 0;
}
반응형
저작자표시 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 14442번[ 벽 부수고 이동하기 2  (1) 2023.09.18
[백준 5719번] 거의 최단 경로  (0) 2023.09.18
[백준 2056번] 작업  (0) 2023.09.01
[백준 2283] 구간 자르기  (0) 2023.08.30
[백준 17521번] Byte Coin  (0) 2023.04.24
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [백준 14442번[ 벽 부수고 이동하기 2
  • [백준 5719번] 거의 최단 경로
  • [백준 2056번] 작업
  • [백준 2283] 구간 자르기
슥지니
슥지니
개발 블로그
  • 슥지니
    슥지니의 코딩노트
    슥지니
  • 전체
    오늘
    어제
    • 분류 전체보기 (198)
      • 알고리즘 문제풀이 (158)
        • 백준 (158)
      • 알고리즘 (6)
      • Node.js (2)
        • MongoDB (1)
        • 기타 (1)
      • spring (0)
      • 가상화폐 (1)
        • 바이낸스(Binance) (1)
      • C++ 테트리스 게임 (0)
      • C++ (10)
      • 안드로이드 프로그래밍 (21)
        • 코틀린 (21)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    C
    C++
    자료구조
    다이나믹 프로그래밍
    BFS
    코틀린
    시뮬레이션
    코틀린을 활용한 안드로이드 프로그래밍
    백준
    콘솔 테트리스 게임
    콘솔
    Kotlin
    그래프
    dp
    우선순위 큐
    백트랙킹
    알고리즘
    그리디
    구현
    dfs
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
슥지니
[백준 1774번] 우주신과의 교감
상단으로

티스토리툴바