PS(Problem Solving)/BOJ

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

JunsuKim 2022. 7. 30.
728x90

문제

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

 

1774번: 우주신과의 교감

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

www.acmicpc.net

문제

최소 비용을 구해야 하기 때문에, MST 알고리즘을 사용하는 문제이다.

따로 어떤 노드부터 시작해라라는 말이 없으므로 크루스칼 알고리즘을 사용하였다.

 

황선자씨는 이미 교감하고 있는 우주신들이 있다.

따라서 우선적으로 이미 교감하고 있는 우주신들을 union을 통해 합집합 연산을 해준다.

 

이후 아직 연결되지 않은 우주신들과의 거리를 구하여 우선순위 큐에 시작점, 도착점, 거리를 넣어준 후, 거리를 기준으로 오름차순 정렬하여 전형적인 크루스칼 알고리즘을 수행해나가면 된다.

소스 코드

import java.util.PriorityQueue
import kotlin.math.pow
import kotlin.math.sqrt

private lateinit var parent: IntArray

data class EdgeInfo(val start: Int, val end: Int, val dist: Double): Comparable<EdgeInfo> {
    override fun compareTo(other: EdgeInfo): Int {
        if(dist > other.dist) return 1
        return -1
    }
}

fun main() = with(System.`in`.bufferedReader()) {
    val (godCnt, alreadyConnect) = readLine().split(" ").map { it.toInt() }

    parent = IntArray(godCnt + 1)
    repeat(godCnt + 1) { i -> parent[i] = i }

    val pos = ArrayList<Pair<Double, Double>>()
    repeat(godCnt) {
        val (y, x) = readLine().split(" ").map { it.toDouble() }
        pos.add(Pair(y, x))
    }

    repeat(alreadyConnect) {
        val (start, end) = readLine().split(" ").map { it.toInt() }
        union(start, end)
    }

    val pq = PriorityQueue<EdgeInfo>()
    for(i in 0 until pos.size) {
        for(j in i + 1 until pos.size) {
            val dist = sqrt((pos[j].first - pos[i].first).pow(2) + (pos[j].second - pos[i].second).pow(2))
            pq.add(EdgeInfo(i+1, j+1, dist))
        }
    }

    var ans = 0.0
    while(pq.isNotEmpty()) {
        val cur = pq.poll()
        if(find(cur.start) != find(cur.end)) {
            union(cur.start, cur.end)
            ans += cur.dist
        }
    }

    println(String.format("%.2f", ans))
}

private fun union(a: Int, b: Int) {
    val aParent = find(a)
    val bParent = find(b)

    parent[bParent] = aParent
}
private fun find(i: Int): Int {
    if(parent[i] == -1) return -1
    if(parent[i] != i) parent[i] = find(parent[i])
    return parent[i]
}
728x90

'PS(Problem Solving) > BOJ' 카테고리의 다른 글

[백준/BOJ] 1368번: 물대기  (0) 2022.08.01
[백준/BOJ] 2589번: 보물섬  (0) 2022.07.31
[백준/BOJ] 10423번: 전기가 부족해  (0) 2022.07.29
[백준/BOJ] 16236번: 아기 상어  (0) 2022.07.29
[백준/BOJ] 6497번: 전력난  (0) 2022.07.28

댓글