차곡차곡 성 쌓기
article thumbnail

문제

 

1414번: 불우이웃돕기

첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 랜선의 길이가 주어진다. i번째 줄의 j번째 문자가 0인 경우는 컴퓨터 i와 컴퓨터 j를 연결하는 랜선이 없음을 의미한다. 그 외의 경우는 랜선

www.acmicpc.net

 

[Gold III] 불우이웃돕기 - 1414

분류

그래프 이론, 최소 스패닝 트리, 문자열

제출 일자

2024년 2월 12일 15:18:15

문제 설명

다솜이는 불우이웃 돕기 활동을 하기 위해 무엇을 할지 생각했다. 마침 집에 엄청나게 많은 랜선이 있다는 것을 깨달았다. 마침 랜선이 이렇게 많이 필요 없다고 느낀 다솜이는 랜선을 지역사회에 봉사하기로 했다.

다솜이의 집에는 N개의 방이 있다. 각각의 방에는 모두 한 개의 컴퓨터가 있다. 각각의 컴퓨터는 랜선으로 연결되어 있다. 어떤 컴퓨터 A와 컴퓨터 B가 있을 때, A와 B가 서로 랜선으로 연결되어 있거나, 또 다른 컴퓨터를 통해서 연결이 되어있으면 서로 통신을 할 수 있다.

다솜이는 집 안에 있는 N개의 컴퓨터를 모두 서로 연결되게 하고 싶다.

N개의 컴퓨터가 서로 연결되어 있는 랜선의 길이가 주어질 때, 다솜이가 기부할 수 있는 랜선의 길이의 최댓값을 출력하는 프로그램을 작성하시오.

입력 

 첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 랜선의 길이가 주어진다. i번째 줄의 j번째 문자가 0인 경우는 컴퓨터 i와 컴퓨터 j를 연결하는 랜선이 없음을 의미한다. 그 외의 경우는 랜선의 길이를 의미한다. 랜선의 길이는 a부터 z는 1부터 26을 나타내고, A부터 Z는 27부터 52를 나타낸다. N은 50보다 작거나 같은 자연수이다.

출력 

 첫째 줄에 다솜이가 기부할 수 있는 랜선의 길이의 최댓값을 출력한다. 만약, 모든 컴퓨터가 연결되어 있지 않으면 -1을 출력한다.

 

 


접근 방법

/*
 * 모든 점 최소비용으로 탐색 -> 최소 비용 트리
 * 엣지 리스트 필요 -> 입력정보로 인접행렬을 만든 후,탐색해서 리스트 생성
 *
 * + 최종 답은 기부할 수 최대 랜선의 길이 -> (가지고 있는 랜선의 길이) - (최소한의 사용)
 *  헤맨 부분
 *  1. 문자와 0이 같이 주어지면 어떻게 파싱해야 될지
 *  2. 대문자보다 소문자의 유니 코드값이 더 큰데, 비용은 대문자가 더 클 때 어떻게 처리해줘야 할지
 */

 

 

풀이 

import java.io.*;
import java.util.*;

public class Main {

    public static BufferedWriter bw;
    public static BufferedReader br;

    public static int [] parent;


    public static void main(String[] args) throws Exception {

        br  = new BufferedReader(new InputStreamReader(System.in));
        bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int N = Integer.parseInt(br.readLine());
        int [][]map = new int[N][N];
        int len = 0;

        for(int i=0; i<N; i++) {
            String aline = br.readLine();
            for(int j=0; j<N; j++) {
                int n = aline.charAt(j) - 'a' +1;
                // 음수라면 대문자이거나 0
                if(n < 0) {
                    if(n == -48)
                        continue;
                    // 대문자
                    n += 58;
                }
                map[i][j] = n;
                len+= n;

            }
        }

        // 우선 순위 큐 생성
        PriorityQueue<Edge> que = new PriorityQueue<Edge>(new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.cost - o2.cost;
            };
        });

        // 간선 추가
        for(int i=0; i<N; i++) {
            for(int j=0; j<N; j++) {
                if(i==j || map[i][j] == 0) continue;

                que.add(new Edge(i,j, map[i][j]));

            }
        }

        // 최소 신장 트리 알고리즘 시작
        int ans = 0;
        int count =0;
        parent = new int[N];
        for(int i=0; i<parent.length; i++)
            parent[i] = i;

        while(!que.isEmpty()) {
            Edge cur = que.poll();
            int a = find(cur.start);
            int b = find(cur.end);

            if(a != b) {
                union(a,b);
                ans += cur.cost;
                count++;
            }
        }

        if(count == N-1) {
            bw.write(len - ans +"");
        }else {
            bw.write("-1");
        }

        bw.flush();
        bw.close();
        br.close();
    }


    public static void union(int a, int b) {
        a = find(a);
        b = find(b);

        if(a == b)
            return;

        parent[b]= a;
    }

    public static int find(int a) {
        if(parent[a] == a) {
            return a;
        }
        return parent[a] = find(parent[a]);
    }
}

class Edge {
    int start;
    int end;
    int cost;

    Edge(int start, int end, int cost){
        this.start = start;
        this.end = end;
        this.cost = cost;
    }


}
728x90
profile

차곡차곡 성 쌓기

@nagrang

포스팅이 좋았다면 "좋아요" 해주세요!