(백준) 다리만들기2 - 17472 [java]

2021. 8. 5. 15:05·알고리즘/백준

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

 

🐢 설명

2차원 맵에 있는 섬들을 직선의 다리를 놓아서 연결하되 다리의 총 길이가 최소가 되도록 하는 문제이다.

 

  1. 모든 섬들을 구분해서 번호를 맺기 위해 DFS를 사용했다.
  2. 만들수 있는 모든 다리를 만들고 다리를 비용이 낮은 순으로 탐색하기 위해 우선순위큐를 사용했다.
  3. 각 모든 섬들을 다리로 묶어서 연결됨을 나타내기위해 union-find를 사용했다
    • 우선순위 큐에 담긴 모든 다리를 하나씩 확인하면서 해당 다리가 잇는 섬이 이미 연결되었는지 안되었는지를 확인하고, 연결이 안되었다면 연결시키고 다리비용을 추가시켰다.
  4. 마지막으로 모든 다리에 대해 비교를 끝내고 모든 섬들의 부모를 확인해서 하나라도 다른 섬이 있다면 연결되지 않았다고 판단했다.

 

🐢코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.PriorityQueue;

public class Main {
    static int N, M;
    static int[][] board;
    static boolean[][] visited;
    static int[] parents;
    static int[] dy = {-1, 1, 0, 0};
    static int[] dx = {0, 0, -1, 1};
    static PriorityQueue<Bridge> pq = new PriorityQueue<>(Comparator.comparingInt(b -> b.len));

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = br.readLine().split(" ");

        N = Integer.parseInt(input[0]);
        M = Integer.parseInt(input[1]);

        board = new int[N][M];

        for (int i = 0; i < N; i++) {
            input = br.readLine().split(" ");
            for (int j = 0; j < M; j++) {
                board[i][j] = Integer.parseInt(input[j]);
            }
        }

        findAllIsland();
        makeAllBridge();
        int answer = matchingBrdige();

        int other = find(parents[1]);
        for (int i = 2; i < parents.length; i++) {
            if (other != find(parents[i])) {
                System.out.println(-1);
                return;
            }
        }
        System.out.println(answer);
    }

    private static int matchingBrdige() {
        int totalBridgeLen = 0;
        while (!pq.isEmpty()) {
            Bridge bridge = pq.poll();

            int landA = find(bridge.landA);
            int landB = find(bridge.landB);

            if (landA != landB) {
                union(landA, landB);
                totalBridgeLen += bridge.len;
            }
        }
        return totalBridgeLen;
    }

    private static void union(int landA, int landB) {
        parents[landA] = landB;
    }

    private static int find(int land) {
        if (parents[land] == land) return land;
        return parents[land] = find(parents[land]);
    }

    private static void makeAllBridge() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (board[i][j] > 0) {
                    setBridge(i, j);
                }
            }
        }
    }

    private static void setBridge(int y, int x) {
        int nowLand = board[y][x];

        for (int d = 0; d < 4; d++) {
            boolean flag = false;
            int ny = y, nx = x;
            int len = 0;

            while (true) {
                ny += dy[d];
                nx += dx[d];

                if (ny < 0 || nx < 0 || ny >= N || nx >= M) break;
                if (board[ny][nx] == nowLand) break;
                if (board[ny][nx] > 0 && len < 2) break;
                if (board[ny][nx] > 0 && len >= 2) {
                    flag = true;
                    break;
                }
                len++;
            }
            if (flag) pq.add(new Bridge(nowLand, board[ny][nx], len));
        }
    }

    private static void findAllIsland() {
        visited = new boolean[N][M];
        int indexing = 1;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (!visited[i][j] && board[i][j] != 0) {
                    DFS(i, j, indexing++);
                }
            }
        }

        parents = new int[indexing];
        for (int i = 1; i < indexing; i++)
            parents[i] = i;
    }

    private static void DFS(int y, int x, int indexing) {
        if (y < 0 || x < 0 || y >= N || x >= M || board[y][x] == 0 || visited[y][x])
            return;

        board[y][x] = indexing;
        visited[y][x] = true;

        for (int d = 0; d < 4; d++) {
            int ny = y + dy[d];
            int nx = x + dx[d];
            DFS(ny, nx, indexing);
        }
    }

    private static class Bridge {
        int landA;
        int landB;
        int len;

        public Bridge(int landA, int landB, int len) {
            this.landA = landA;
            this.landB = landB;
            this.len = len;
        }
    }
}
🐢 마무리
반응형
저작자표시 (새창열림)

'알고리즘 > 백준' 카테고리의 다른 글

(백준) 단어암기 - 18119 [java]  (0) 2021.08.09
(백준) 20437 - 문자열 게임 2 [java]  (1) 2021.08.09
(백준) 13904 - 과제 [java]  (1) 2021.08.04
(백준) 13422 - 도둑 [java]  (0) 2021.08.04
(백준) 가장 가까운 공통 조상 - 3584 [java]  (0) 2021.08.01
'알고리즘/백준' 카테고리의 다른 글
  • (백준) 단어암기 - 18119 [java]
  • (백준) 20437 - 문자열 게임 2 [java]
  • (백준) 13904 - 과제 [java]
  • (백준) 13422 - 도둑 [java]
구름뭉치
구름뭉치
구름의 개발일기장
    반응형
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (289) N
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (5) N
        • 아파치 카프카 (9)
        • 클린 코드 (4)
        • 디자인 패턴의 아름다움 (2)
        • 모던 자바 인 액션 (7)
        • JVM 스레드 딥다이브 (7)
      • Web (25)
        • 정리글 (20)
        • GraphQL 정리글 (2)
        • Jenkins 정리글 (3)
      • 취업 (6)
      • CS (77)
        • 네트워크 전공 수업 정리 (11)
        • OSI 7계층 정리 (12)
        • 운영체제 정리 (19)
        • 데이터베이스 정리 (5)
        • MySql 정리 (17)
        • GoF의 Design Pattern 정리 (12)
      • 알고리즘 (70)
        • 백준 (56)
        • 프로그래머스 (12)
        • 알고리즘 정리본 (1)
      • 기초 지식 정리 (2)
      • 일상 (8)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    류블라냐
    mx master s3 for mac
    부다페스트
    마우스
    키보드 손목 받침대
    레이저
    마우스 패드
    동유럽
    크로아티아
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
구름뭉치
(백준) 다리만들기2 - 17472 [java]
상단으로

티스토리툴바