Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- PS
- 완전탐색
- deque
- 재귀함수
- COSPROJAVA1급
- 구현
- 백준
- QUICKSTARTGUIDE
- 01BFS
- YBMCOS
- 자바PS
- 다익스트라
- 다이나믹프로그래밍
- 세그먼트트리
- BFS
- 네트워크플로우
- dp
- 알고리즘
- COSPRO
- 시뮬레이션
- 이젠 골드구현도 어렵네..
- 취득후기
- 우선순위큐
- 백준코딩테스트
- 엘라스틱서치
- java
- 게더타운시작
- DFS
- spring
- GatherTown
Archives
- Today
- Total
공부공간
BOJ - 2887 ) 행성 터널 본문
https://www.acmicpc.net/problem/2887
2887번: 행성 터널
문제 때는 2040년, 이민혁은 우주에 자신만의 왕국을 만들었다. 왕국은 N개의 행성으로 이루어져 있다. 민혁이는 이 행성을 효율적으로 지배하기 위해서 행성을 연결하는 터널을 만들려고 한다. �
www.acmicpc.net
3차원 공간에서 모든 지점의 최소스패닝트리를 구하는 문제이다.
최악의 경우 N이 10만개일 때, 자신을 제외한 99999개를 구해야한다.
10만*10만의 연산을 통하여 간선길이를 정렬하면 메모리초과와 시간초과가나기때문에,
정렬을 통하여 m번째 노드는 m-1 , m+1번째만 계산을 통한다. ...m-2, m+2 ...은 정렬이 되어있기 때문에
최소가 보장되지 않는다. 이를 X ,Y, Z 에대해서 한번씩 진행하여 최솟값을 산출한다.
1
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class 행성터널 {
public static class node{
int number,x,y,z;
public node(int number, int x, int y, int z) {
this.number = number;
this.x = x;
this.y = y;
this.z = z;
}
}
public static int parent[];
public static void main(String[] args) throws Exception {
BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
ArrayList<node> al = new ArrayList<>();
int n = Integer.parseInt(st.nextToken());
for(int i = 0 ; i < n ; i ++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int z = Integer.parseInt(st.nextToken());
al.add(new node(i,x,y,z));
}
// start , end ,cost
PriorityQueue<int []> pq = new PriorityQueue<>(new Comparator<int []>() {
@Override
public int compare(int[] o1, int[] o2) {
if(o1[2] > o2[2]) {return 1;}
else if(o1[2] == o2[2]) {return 0;}
else return -1;
}
});
Collections.sort(al, new Comparator<node>() {
@Override
public int compare(node o1, node o2) {
//x를 기준으로 정렬
return o1.x - o2.x;
}
});
for(int i = 0 ; i < n ; i ++) {
// 인접한 노드끼리 최단거리 계산
if( i-1 >=0) {// i-1 에서 i 까지의 최단거리 계산
pq.add(new int[] {al.get(i-1).number , al.get(i).number , compute(al.get(i-1).x , al.get(i).x , al.get(i-1).y , al.get(i).y , al.get(i-1).z , al.get(i).z )});}
if( i+1 <n ) {pq.add(new int[] {al.get(i).number , al.get(i+1).number , compute(al.get(i).x , al.get(i+1).x , al.get(i).y , al.get(i+1).y , al.get(i).z , al.get(i+1).z )});}
}
Collections.sort(al, new Comparator<node>() {
@Override
public int compare(node o1, node o2) {
//y를 기준으로 정렬
return o1.y - o2.y;
}
});
for(int i = 0 ; i < n ; i ++) {
// 인접한 노드끼리 최단거리 계산
if( i-1 >=0) {// i-1 에서 i 까지의 최단거리 계산
pq.add(new int[] {al.get(i-1).number , al.get(i).number , compute(al.get(i-1).x , al.get(i).x , al.get(i-1).y , al.get(i).y , al.get(i-1).z , al.get(i).z )});}
if( i+1 <n ) {pq.add(new int[] {al.get(i).number , al.get(i+1).number , compute(al.get(i).x , al.get(i+1).x , al.get(i).y , al.get(i+1).y , al.get(i).z , al.get(i+1).z )});}
}
Collections.sort(al, new Comparator<node>() {
@Override
public int compare(node o1, node o2) {
//z를 기준으로 정렬
return o1.z - o2.z;
}
});
for(int i = 0 ; i < n ; i ++) {
// 인접한 노드끼리 최단거리 계산
if( i-1 >=0) {// i-1 에서 i 까지의 최단거리 계산
pq.add(new int[] {al.get(i-1).number , al.get(i).number , compute(al.get(i-1).x , al.get(i).x , al.get(i-1).y , al.get(i).y , al.get(i-1).z , al.get(i).z )});}
if( i+1 <n ) {pq.add(new int[] {al.get(i).number , al.get(i+1).number , compute(al.get(i).x , al.get(i+1).x , al.get(i).y , al.get(i+1).y , al.get(i).z , al.get(i+1).z )});}
}
int time = 0 , answer = 0;
parent= new int[n];
make();
while(time!=n-1) {
int [] now = pq.poll();
if(union(now[0] , now[1])) {
time++;
answer +=now[2];
}
}System.out.println(answer);
}
private static void make() {
for(int i =0 ; i < parent.length; i++) {
parent[i] =i ;
}
}
private static int findp(int x) {
if(parent[x] ==x ) return x;
else return findp(parent[x]);
}
private static boolean union(int x , int y) {
x = findp(x); y = findp(y);
if(x==y) return false;
if(x > y) parent[x] =y;
else parent[y] = x;
return true;
}
private static int compute(int x, int x2, int y, int y2, int z, int z2) {
return Math.min(Math.min(Math.abs(x-x2), Math.abs(y - y2)), Math.abs(z-z2));
}
}
'알고리즘 > 구현,시뮬' 카테고리의 다른 글
BOJ - 1846 ) 장기 (1) | 2020.07.29 |
---|---|
BOJ - 18111 ) 마인크래프트 (0) | 2020.07.22 |
BOJ - 6497 ) 전력난 (0) | 2020.07.07 |
BOJ - 1647 ) 도시분할계획 (0) | 2020.07.07 |
BOJ - 2230 ) 수 고르기 (0) | 2020.06.29 |
Comments