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 | 29 | 30 |
Tags
- 소가길을건너간이유6
- 별자리 만들기
- 날짜일수
- Error fetching remote repo 'origin'
- 2167. 2차원 배열의 합
- 호석이두마리치킨
- 알고리즘
- 이산수학
- 14466
- CMD
- jenkins
- EC2
- 프로그래머스
- documentationpluginsbootstrapper
- 설정
- 이클립스
- 2108_통계학
- Eclipse
- 백준
- 투에모스문자열
- dockercompose
- 20055
- to display the conditions report re-run your application with 'debug' enabled
- SpringBoot
- 자바
- Error
- 18222
- Java
- 21278
- docker
Archives
- Today
- Total
계단을 오르듯이
[JAVA] 21278. 호석이 두 마리 치킨 본문
플로이드-와샬 알고리즘을 이용해야한다.
플로이드 와샬 알고리즘은 O(n^3)의 시간복잡도를 가지며, 모든 정점의 이동거리를 구할 수 있다.
총 n개의 정점이 있다면 1개의 노드가 n-1의 노드까지의 연결 거리를 모두 알 수 있다.
우선 플로이드-와샬 알고리즘을 통해 서로의 연결 상태(간선의 개수)를 알 수 있고, 간선의 개수만큼의 시간이 걸린다.
현재 문제에서는 왕복의 거리이므로 간선의 수 한개당 2의 시간이 걸린다고 생각하고 시간 배열을 채웠다.
그 후, 치킨집을 조합으로 하여 모든 경우의 수를 통해 최소의 거리시간을 구하였다.
우선 2개의 치킨집을 조합으로 구한 후 모든 정점에서 2개의 치킨집 중 가장 가까운 치킨집을 구하여 그 시간을 모든 총 시간을 나타내는 시간에 더해주었고, 이렇게 모든 경우를 통해 최소의 거리인 문제를 해결하였다.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package algo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class B_21278_호석이두마리치킨 {
static int totalmax = 100001;
static int a, b;
static int INF = 100001;
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] dist = new int[N][N];
for (int[] d : dist) { // 모든 정점 사이의 거리를 INF(최대)로 셋팅
Arrays.fill(d, INF);
}
for (int i = 0; i < N; i++) {
dist[i][i] = 0;
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(in.readLine(), " ");
int a = Integer.parseInt(st.nextToken()) - 1;
int b = Integer.parseInt(st.nextToken()) - 1;
dist[a][b] = 2; // 왕복
dist[b][a] = 2;
}
// 플로이드-와샬 알고리즘을 통해 모든 거리의 최소값을 구한다.
allDist(N, dist);
// 두개의 치킨집을 통해 최소거리를 구한다.
for (int i = 0; i < N; i++) { // 첫번째 치킨집
for (int j = i + 1; j < N; j++) { // 두번째 치킨집
int[] chicken = { i, j };
reDist(chicken, N, dist);
}
}
System.out.println(a + " " + b + " " + totalmax);
}
// 치킨집 추가 - 다시 최소거리 구하기
private static void reDist(int[] chicken, int N, int[][] dist) {
int sum = 0; // 현재 치킨집일 경우의 총 거리합
for (int i = 0; i < N; i++) {
int Min = Integer.MAX_VALUE;
for (int j = 0; j < 2; j++) {
int idx = chicken[j];
Min = Math.min(Min, dist[i][idx]); // 2개의 치킨집 중 가장 가까운 치킨집 선택
}
sum += Min;
}
if (sum < totalmax) { // 가장 최소의 거리 갱신
totalmax = sum;
a = chicken[0] + 1;
b = chicken[1] + 1;
}
}
// 플로이드-와샬
private static void allDist(int N, int[][] dist) {
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
}
}
|
cs |
'알고리즘 > 백준_JAVA' 카테고리의 다른 글
[JAVA] 프로그래머스 - 카펫 (0) | 2022.01.31 |
---|---|
[JAVA] 14916. 거스름돈 (0) | 2022.01.28 |
[JAVA] 14466. 소가 길을 건너간 이유 6 (0) | 2022.01.27 |
[JAVA] 20055. 컨베이어 벨트 위의 로봇 (0) | 2022.01.27 |
[JAVA] 2164. 카드 2 (0) | 2022.01.26 |