알고리즘

백준 17490번 일감호에 다리 놓기 (JAVA)

박카스마시며코딩 2022. 5. 21. 22:52

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

 

17490번: 일감호에 다리 놓기

2번, 4번, 5번 강의동과 와우도를 연결하면 가지고 있는 돌 내에서 징검다리를 완성할 수 있다. 이 때, 어떤 한 강의동에서 다른 모든 강의동으로 가는 길이 존재한다.

www.acmicpc.net

 

저는 해당 문제를 크루스칼을 통해서 문제를 해결하였습니다.

크루스칼을 통해 가장 작은 엣지부터 고려하여 mst를 만들었습니다.

이 문제의 어려운 점은 이웃한 표시하는 것과 이웃을 끊는 것이라고 생각합니다.

저는 parent를 통해 그룹을 지었고 , 각각의 parent는 이전 값을 참조하도록 하고 1은 n을 참조하도록 하였습니다.

이렇게 했을 때 m이 0(즉, 끊는 경우가 없다면) findSet에서 사이클이 존재하기 때문에 m이 0 일때는 바로 YES를 출력하도록 하였습니다. 또한, 1일 때는 한방향의 연결만 끊기기 때문에 결국 모두 연결되어 있어 바로 YES를 출력하였습니다.

끊는 것은 해당 점은 parent은 그 인덱스로 변경하여 이웃점과에 대한 연결을 끊었습니다.

 

package BOJ.mst;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.Function;

public class BOJ_17490 {
    private static class Edge{
        int start;
        int end;
        long weight;

        public Edge(int start, int end, long weight) {
            this.start = start;
            this.end = end;
            this.weight = weight;
        }
    }
    private static int findSet(int now , int[] parent){
        if(now == parent[now]){
            return now;
        }
        return parent[now] = findSet(parent[now],parent);
    }
    private static boolean unionSet(int a, int b,int[] parent){
        int aParent = findSet(a,parent);
        int bParent = findSet(b,parent);
        if(aParent == bParent){
            return false;
        }
        parent[aParent] = bParent;
        return true;
    }
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine()," ");
        Function<String,Integer> stoi = Integer::parseInt;
        Function<String,Long> stol = Long::parseLong;
        int n = stoi.apply(st.nextToken());
        int m = stoi.apply(st.nextToken());
        long k = stol.apply(st.nextToken());
        int[] parent = new int[n+1];
        for(int i = 1 ; i <= n ; i++){
            parent[i] = i-1;
        }
        parent[1] = n;
        st = new StringTokenizer(br.readLine()," ");
        List<Edge> edges = new LinkedList<>();
        for(int i = 1 ; i <= n ; i++){
            long weight = stol.apply(st.nextToken());
            edges.add(new Edge(0,i,weight));
        }
        for(int i = 0 ; i < m ; i++){
            st = new StringTokenizer(br.readLine()," ");
            int a = stoi.apply(st.nextToken());
            int b = stoi.apply(st.nextToken());
            int min = Math.min(a,b);
            int max = Math.max(a,b);
            if(min == 1 && max == n){
                parent[1] = 1;
                continue;
            }
            parent[max] = max;
        }
        if(m <= 1){
            System.out.println("YES");
            return ;
        }
        Collections.sort(edges,(o1,o2)->{
            if(o1.weight > o2.weight){
                return 1;
            }
            if(o1.weight < o2.weight){
                return -1;
            }
            return 0;
        });
        long result = 0;
        for(Edge edge : edges){
            if(unionSet(edge.start,edge.end,parent)){
                result += edge.weight;
            }
        }
//        System.out.println(Arrays.toString(parent));
//        System.out.println(result);
        if(result > k){
            System.out.println("NO");
        }else{
            System.out.println("YES");
        }
    }

}

'알고리즘' 카테고리의 다른 글

프로그래머스 GPS (JAVA)  (0) 2022.05.23
백준 15810번 풍선 공장  (0) 2022.05.22
프로그래머스 프렌즈4블록  (0) 2022.05.20
백준 2186번 문자판 (JAVA)  (0) 2022.05.19
백준 6236번 용돈 관리 (JAVA)  (0) 2022.05.18