(백준) 호석이 두 마리 치킨 - 21278 [JAVA]

2021. 7. 29. 13:49·알고리즘/백준

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

 

21278번: 호석이 두 마리 치킨

위의 그림과 같이 1번과 2번 건물에 치킨집을 짓게 되면 1번부터 5번 건물에 대해 치킨집까지의 왕복 시간이 0, 0, 2, 2, 2 로 최소가 된다. 2번과 3번 건물에 지어도 동일한 왕복 시간이 나오지만 더

www.acmicpc.net

 

🐢 해설

먼저 빌딩과 도로가 존재하고 양방향이며 도로의 비용이 1로 고정되어 있으므로 해당 간선과 정점을 가지고 각 빌딩에 대해서 다른 모든 빌딩에 대한 거리 최소 비용을 구해야한다.

 

이후 구한 거리값을 가지고 어디에 치킨집을 차렸을 때(2개로 고정) 모든 빌딩의 왕복 합이 낮은지 구하면 된다.

 

특정 빌딩이 아니라 모든 빌딩에 대해 최소 거리값을 구해야 하므로 플로이드 와샬을 사용해서 거리 비용을 구한다. 플로이드와샬의 시간복잡도는 N^3인데 총 100개의 정점이 존재할 수 있으므로 최대 100만번의 비교가 발생하므로 시간복잡도는 충분하다.

 

거리비용 배열을 이용해서 이제 N개의 빌딩에 대해 2개의 치킨집을 차리는 순서가 없는 경우를 모두 뽑는것으로 nC2를 구하면된다. 이는 최대 100 * 99 / 2 = 4950번의 경우의 수가 발생한다.

 

총 시간복잡도는 5000 + 100만번으로 O(N^3)이다.

 

왕복의 거리를 구할 때는 왕복이 가능하므로 치킨집이 없는 i번 빌딩에서 치킨집 빌딩 중 가장 짧은 거리값 * 2이 최소 왕복 비용이다. 이 왕복 비용을 모든 빌딩들에 대해서 더하고, 총 합을 최소로 갖도록 갱신하면 된다.

 

탐색은 순차적으로 이뤄지므로 따로 건물의 번호에 대해서는 비교할 필요없이 갱신만 해주면된다.

🐢 코드
import java.util.*;
import java.io.*;

public class Main {
    static final int INF = 10000001;
    static int N, M, Min = INF, I, J;
    static int[][] time;

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

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        time = new int[N + 1][N + 1];
        for (int i = 1; i <= N; i++) {
            Arrays.fill(time[i], INF);
            time[i][i] = 0;
        }

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int u = Integer.parseInt(st.nextToken());
            int v = Integer.parseInt(st.nextToken());
            time[u][v] = 1;
            time[v][u] = 1;
        }

        floyd();

        // nC2
        boolean[] visited = new boolean[N + 1];
        int[] selected = new int[2];
        Arrays.fill(visited, false);
        comb(1, 0, 2, visited, selected);

        System.out.println(I + " " + J + " " + Min);
    }

    private static void comb(int start, int select, int max, boolean[] visited, int[] selected) {
        if (select == max) {

            int sum = 0;
            for (int i = 1; i < N + 1; i++) {
               if (visited[i]) continue;
                int min = INF;
                for (int k : selected)
                    min = Math.min(time[i][k], min);
                sum += min * 2;
            }

            if (Min > sum) {
                Min = sum;
                I = selected[0];
                J = selected[1];
            }
            return;
        }

        for (int i = start; i < N + 1; i++) {
            if (!visited[i]) {
                visited[i] = true;
                selected[select] = i;
                comb(i + 1, select + 1, max, visited, selected);
                visited[i] = false;
            }
        }
    }

    private static void floyd() {
        for (int k = 1; k <= N; k++) {
            for (int i = 1; i <= N; i++) {
                for (int j = 1; j <= N; j++) {
                    if (time[i][j] > time[i][k] + time[k][j]) {
                        time[i][j] = time[i][k] + time[k][j];
                    }
                }
            }
        }
    }
}
반응형
저작자표시 (새창열림)

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

(백준) 동전 - 9084 [java]  (1) 2021.08.01
(백준) 2225 - 합분해 [java]  (1) 2021.07.31
(백준) 호석사우루스 - 22255 [JAVA]  (0) 2021.07.26
(백준) 얼음 미로 - 20926  (0) 2021.07.26
(백준) 트리의 기둥과 가지 - 20924  (0) 2021.07.25
'알고리즘/백준' 카테고리의 다른 글
  • (백준) 동전 - 9084 [java]
  • (백준) 2225 - 합분해 [java]
  • (백준) 호석사우루스 - 22255 [JAVA]
  • (백준) 얼음 미로 - 20926
구름뭉치
구름뭉치
구름의 개발일기장
  • 구름뭉치
    구름 개발일기장
    구름뭉치
  • 전체
    오늘
    어제
    • ALL (294)
      • 프로젝트 (23)
        • 토스페이먼츠 PG 연동 시리즈 (12)
        • JWT 방식 인증&인가 시리즈 (6)
        • 스우미 웹 애플리케이션 프로젝트 (1)
        • 스프링부트 기본 보일러 플레이트 구축 시리즈 (2)
        • 마이크로서비스 아키텍쳐 시리즈 (1)
      • 스프링 (43)
        • 스프링부트 API 설계 정리 (8)
        • 스프링부트 RestAPI 프로젝트 (18)
        • 스프링부트 WebSocket 적용기 (3)
        • 스프링 JPA 정리 시리즈 (5)
        • 스프링 MVC (5)
        • 스프링 배치 (2)
        • 토비의 스프링 정리 (2)
      • 기술 학습 (10)
        • 아파치 카프카 (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
구름뭉치
(백준) 호석이 두 마리 치킨 - 21278 [JAVA]
상단으로

티스토리툴바