[백준/JAVA] 4386_별자리 만들기

2023. 6. 22. 18:35· 🖥️Computer Science/알고리즘
목차
  1. 백준🔗
  2. 문제
  3. 간단 풀이
  4. 코드
  5. 참고 자료

백준🔗

 

4386번: 별자리 만들기

도현이는 우주의 신이다. 이제 도현이는 아무렇게나 널브러져 있는 n개의 별들을 이어서 별자리를 하나 만들 것이다. 별자리의 조건은 다음과 같다. 별자리를 이루는 선은 서로 다른 두 별을 일

www.acmicpc.net

 

문제

 

 

간단 풀이

별들을 최소 비용으로 모두 잇는 문제이기 때문에 최소 스패닝 트리(MST)로 생각하고 접근하면 된다.

 

다만, 간선이 미리 주어지는 것이 아니라 어떤 정점이든 모두 이을 수 있다는 것이 이전에 풀었던 문제들과 다른 포인트인 것 같다.

따라서 크루스칼과 프림 중 프림 방식을 선택했다. 이전 포스팅

(👉 2023.06.16 - [알고리즘/백준] - [백준/JAVA] 1197_최소 스패닝 트리)

에서도 얘기했듯이 크루스칼은 최소 비용의 '간선'을 선택하는 것이기 때문에 시작 단계에서 모든 간선을 가중치에 따라 오름차순으로 정렬해 둔 뒤에 사이클이 생기지 않도록 선택해 나가게 되는데, 이 문제에서는 가능한 간선의 개수가 n*(n+1)/2개로 정점 개수에 비해 너무 많기 때문에 크루스칼보다 프림이 더 효율적이라고 생각했기 때문이다.

 

따라서 프림을 우선순위 큐를 사용해서 구현했다. 

1) 임의의 정점을 하나 선택해서 시작한다.

2) 아직 방문하지 않은 정점들 중 최소 비용의 간선이 존재하는 '정점'을 선택한다.

3) 해당 정점에서 갈 수 있는 미방문 정점들을 우선순위 큐에 넣는다.

4) 모든 정점이 선택될 때까지 2, 3번 과정을 반복한다.

 

 

코드

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

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine()); // 별 개수
		double[][] star = new double[n][2];
		for (int i = 0; i < n; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			star[i][0] = Double.parseDouble(st.nextToken());
			star[i][1] = Double.parseDouble(st.nextToken());
		}

		boolean[] visited = new boolean[n];
		PriorityQueue<Edge> pq = new PriorityQueue<>(new Comparator<Edge>() {
			@Override
			public int compare(Edge o1, Edge o2) {
				if (o1.d > o2.d) {
					return 1;
				} else {
					return -1;
				}
			}
		});
		// 시작 정점 뽑기
		visited[0] = true;
		for (int i = 1; i < n; i++) {
			pq.add(new Edge(0, i, getDistance(star[0][0], star[0][1], star[i][0], star[i][1])));
		}
		int pick = 1;
		double cost = 0;
		while (pick != n) {
			Edge cur = pq.poll();
			if (visited[cur.ed])
				continue;
			visited[cur.ed] = true;
			pick++;
			cost += cur.d;
			for (int i = 1; i < n; i++) {
				if (!visited[i]) {
					pq.add(new Edge(cur.ed, i, getDistance(star[cur.ed][0], star[cur.ed][1], star[i][0], star[i][1])));
				}
			}
		}
		System.out.println(Math.floor(cost * 100) / 100.00);
	}

	static double getDistance(double x1, double y1, double x2, double y2) {
		return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
	}

	static class Edge {
		int st, ed;
		double d;

		public Edge(int st, int ed, double d) {
			this.st = st;
			this.ed = ed;
			this.d = d;
		}
	}
}

 

참고 자료

 

  1. 백준🔗
  2. 문제
  3. 간단 풀이
  4. 코드
  5. 참고 자료
'🖥️Computer Science/알고리즘' 카테고리의 다른 글
  • [백준/JAVA] 9466_텀 프로젝트
  • [백준/JAVA] 2239_스도쿠
  • [백준/JAVA] 17404_RGB거리 2
  • [백준/JAVA] 7579_앱
유댕둥당
유댕둥당
유댕둥당
유댕's log
유댕둥당
글쓰기 관리자
전체
오늘
어제
  • 카테고리 (78)
    • 🖥️Computer Science (34)
      • 알고리즘 (34)
    • 🔠Language (5)
      • Java (0)
      • Kotlin (3)
      • C (2)
    • 📥SQL (7)
      • Oracle (6)
    • ♾️DevOps (7)
      • Docker (7)
      • Kubernetes (0)
    • 🐱Git (5)
    • 📁PJT (2)
    • 🧑‍💻Lecture (7)
      • SSAFY (3)
      • 스파르타 코딩클럽 (4)
    • 🎁일상 (11)
      • 국내여행 (4)
      • 해외여행 (0)
      • 일본생활 (7)

블로그 메뉴

  • 👉인스타(SSAFYcial) @ssafycial_yujung
  • 👉인스타(개인) @ik_yu_jung

공지사항

인기 글

태그

  • 컨테이너
  • 도커
  • 자전거탄풍경
  • dockerfile
  • 독도박물관
  • 일본
  • MySQL
  • 워드프레스
  • SQL
  • 티스토리챌린지
  • 통신사
  • 볼륨
  • 라인모
  • Oracle
  • 오라클
  • C언어
  • docker
  • 회원가입
  • 썬플라워
  • 오블완

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
유댕둥당
[백준/JAVA] 4386_별자리 만들기
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.