[백준 16562] 친구비(Java)

최민길(Gale)·2023년 11월 18일
1

알고리즘

목록 보기
151/172

문제 링크 : https://www.acmicpc.net/problem/16562

이 문제는 유니온 파인드를 이용하여 풀 수 있습니다.

친구의 친구는 친구다 라는 명제를 이용하여 친구 관계를 하나의 그룹으로 유니온 파인드를 이용하여 묶어줍니다. 이 때 친구 비용이 더 적은 인덱스를 부모 인덱스로 하여 부모 배열을 채워줍니다.

이후 각 친구 별 루트 인덱스를 확인하여 체크되어있지 않았다면 체크 후 그 값을 결과에 더하고 현재 친구 인덱스 역시 체크를 진행해줍니다. 이 때 루트 인덱스 대신 부모 인덱스를 탐색한다면 1단계의 부모만 탐색 가능하고 그 이후 단계를 탐색할 수 없기 때문에 find를 이용한 루트 인덱스를 탐색해야 하며, 루트 인덱스와 현재 인덱스 모두 체크를 해주어야 중복되어 더해지지 않습니다.

다음은 코드입니다.

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

class Main{
    static int[] cost;
    static int[] parent;

    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        cost = new int[N+1];
        parent = new int[N+1];
        st = new StringTokenizer(br.readLine());
        for(int i=1;i<=N;i++) cost[i] = Integer.parseInt(st.nextToken());
        for(int i=0;i<=N;i++) parent[i] = i;

        for(int i=0;i<M;i++){
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            if(a > b) union(b,a);
            else union(a,b);
        }

        long cnt = 0;
        boolean[] check = new boolean[N+1];
        for(int i=1;i<=N;i++){
            int idx = find(i);

            if(!check[idx]){
                cnt += cost[idx];
                check[idx] = true;
            }

            check[i] = true;
        }

        if(cnt > k) System.out.println("Oh no");
        else System.out.println(cnt);
    }

    static void union(int a, int b){
        a = find(a);
        b = find(b);
        if(cost[a] > cost[b]) parent[a] = b;
        else parent[b] = a;
    }

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

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글