b1647. 도시 분할 계획

2024. 11. 12. 19:10·Algorithm & Data Structures/BOJ

 

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

 

 

 

이 문제는 크루스칼 알고리즘을 사용해 최소 스패닝 트리(MST)를 구하면서

가장 큰 간선 비용을 제외해 두 개의 연결된 부분으로 나누는 문제다.

목표는 모든 정점을 최소 비용으로 연결하는 트리를 구성하되,

가장 큰 비용의 도로를 제외해 두 개의 분리된 부분으로 만드는 것이다.

 

먼저 main 메서드에서 정점 개수 N과 간선 개수 M을 입력받고,

유니온-파인드를 위한 부모 배열 p를 초기화한다.

각 간선의 정보를 입력받아 우선순위 큐 pq에 저장하며,

큐는 간선의 비용을 기준으로 오름차순 정렬된다.

 

calculate 메서드는 크루스칼 알고리즘을 사용해 MST를 구한다.

우선순위 큐에서 가장 작은 간선부터 하나씩 꺼내어,

두 정점이 이미 연결되어 있지 않은 경우 유니온 연산으로 연결한다.

이때 MST의 총 비용을 sum에 더하고, 가장 큰 간선의 비용을 max에 기록한다.

 

마지막으로 MST의 총 비용에서 가장 큰 간선 비용을 뺀 값을 반환해

두 개의 최소 비용 연결 그래프를 만들기 위한 최소 비용을 구한다.

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    private static int[] p;
    private static PriorityQueue<int[]> pq;

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

    private static void union(int a, int b){
        p[find(a)] = find(b);
    }

    private static int calculate(){
        int max = Integer.MIN_VALUE, sum = 0;

        while(!pq.isEmpty()){
            int[] arr = pq.poll();
            if(find(arr[0]) != find(arr[1])){
                union(arr[0], arr[1]);
                max = Math.max(max, arr[2]);
                sum += arr[2];
            }
        }
        return sum - max;
    }

    public static void main(String[] args) throws IOException {
        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());
        p = new int[N+1];
        pq = new PriorityQueue<>(Comparator.comparingInt(o -> o[2]));

        for(int i = 0 ; i < N ; i++){
            p[i] = i;
        }

        for(int i = 0 ; i < M ; i++){
            st = new StringTokenizer(br.readLine());
            int[] arr = {Integer.parseInt(st.nextToken())
                    ,Integer.parseInt(st.nextToken())
                    ,Integer.parseInt(st.nextToken())};
            pq.add(arr);
        }
        System.out.println(calculate());
    }
}

 

'Algorithm & Data Structures > BOJ' 카테고리의 다른 글

b1799. 비숍  (1) 2024.11.20
b1766. 문제집  (1) 2024.11.14
b1644 소수의 연속합  (0) 2024.11.08
b1509. 펠린드롬 분할  (0) 2024.11.06
b1202. 보석도둑  (0) 2024.11.04
'Algorithm & Data Structures/BOJ' 카테고리의 다른 글
  • b1799. 비숍
  • b1766. 문제집
  • b1644 소수의 연속합
  • b1509. 펠린드롬 분할
Geisha
Geisha
개발 일기
  • Geisha
    Geisha
    Geisha
  • 전체
    오늘
    어제
    • 분류 전체보기 (315) N
      • Algorithm & Data Structures (237) N
        • BOJ (95) N
        • SWEA (1)
        • Programers (137)
        • Data Structures (3)
      • DB (25)
        • SQL (19)
        • RDBMS (2)
      • Java (1)
        • Class (1)
      • Spring (5)
        • Spring MVC (1)
        • Annotations (1)
      • CS (36)
        • 운영체제 (13)
        • 네트워크 (5)
      • Tool (6)
        • Git (5)
        • AWS (1)
      • Project (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    binarySearch
    programmers
    Stack
    BFS
    Java
    골드
    PriorityQueue
    unionfind
    후위순회
    백트래킹
    Dijkstra
    algorithm
    SQL
    유니온파인드
    구현
    투포인터
    dp
    Union-Find
    전위순회
    DynamicProgramming
    알고리즘
    다익스트라
    동적계획법
    이분탐색
    baekjoon
    dfs
    경로압축
    스택
    프로그래머스
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Geisha
b1647. 도시 분할 계획
상단으로

티스토리툴바