07
22

문제 설명

n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.

다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.

제한사항

  • 섬의 개수 n은 1 이상 100 이하입니다.
  • costs의 길이는 ((n-1) * n) / 2 이하입니다.
  • 임의의 i에 대해, costs[i][0] 와 costs[i] [1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i] [2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.
  • 같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.
  • 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.
  • 연결할 수 없는 섬은 주어지지 않습니다.

입출력 예

ncostsreturn

4 [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] 4

입출력 예 설명

costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다.

 

문제풀이

섬과 섬 사이의 가중치를 기준으로 오름차순으로 먼저 정렬한다. 그 후 섬과 섬 사이에 연결이 될 때마다 그 섬에 그룹명을 적는다. 만약 섬  2개가 그룹 기본값인 0이면 그룹명에 +1을 하여 새로운 그룹명을 적어주며 섬 1개가 기본값이면 나머지 섬 1개의 그룹명을 똑같이 적어준다. 두 섬 전부 기본 그룹명(0)이 아닌 다른 그룹명을 가지고 있으면 하나의 그룹명으로 두 그룹을 합친다. 이렇게 모든 점을 하나의 그룹으로 만들면서 가중치를 계산해 결과를 도출한다.

 

using System;

public class Solution {
    public int solution(int n, int[,] costs) {
        int answer = 0;
        if(n > 1)
            {
                int[] tempArray = new int[3];
                for (int i = 0; i < (costs.Length / 3); i++)
                {
                    for (int j = i+1; j < (costs.Length / 3); j++)
                    {
                        if(costs[i,2] > costs[j,2])
                        {
                            tempArray[0] = costs[i, 0];
                            tempArray[1] = costs[i, 1];
                            tempArray[2] = costs[i, 2];

                            costs[i, 0] = costs[j, 0];
                            costs[i, 1] = costs[j, 1];
                            costs[i, 2] = costs[j, 2];

                            costs[j, 0] = tempArray[0];
                            costs[j, 1] = tempArray[1];
                            costs[j, 2] = tempArray[2];
                        }
                    }
                }

                int[] check = new int[n];

                int iCount = 1;
                for (int i = 0; i < (costs.Length) / 3; i++)
                {
                    if (check[costs[i, 0]] == 0 && check[costs[i, 1]] == 0)
                    {
                        check[costs[i, 0]] = iCount;
                        check[costs[i, 1]] = iCount;
                        answer = answer + costs[i, 2];
                        iCount++;
                    }
                    else if(check[costs[i,0]] == 0)
                    {
                        check[costs[i, 0]] = check[costs[i, 1]];
                        answer = answer + costs[i, 2];
                    }
                    else if(check[costs[i,1]] == 0)
                    {
                        check[costs[i, 1]] = check[costs[i, 0]];
                        answer = answer + costs[i, 2];
                    }
                    else if(check[costs[i,0]] != check[costs[i,1]])
                    {
                        int number = check[costs[i, 1]];
                        for(int j = 0; j < check.Length; j++)
                        {
                            if(check[j] == number)
                            {
                                check[j] = check[costs[i, 0]];
                            }
                        }
                        answer = answer + costs[i, 2];
                    }
                }
            }
        return answer;
    }
}

 

https://programmers.co.kr/learn/courses/30/lessons/42861

 

코딩테스트 연습 - 섬 연결하기

4 [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] 4

programmers.co.kr

 

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

기능개발(레벨2, C#)  (1) 2021.11.30
K번째수(레벨1, C#)  (0) 2021.11.29
숫자 문자열과 영단어(레벨1, C#)  (0) 2021.11.26
조이스틱(레벨2, C#)  (0) 2020.07.22
종이접기(레벨 3, C#)  (0) 2020.07.22
COMMENT