Skip to content

Commit 9affbe1

Browse files
committed
[Gold III] Title: 다리 만들기, Time: 160 ms, Memory: 74528 KB -BaekjoonHub
1 parent c0bd67e commit 9affbe1

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# [Gold III] 다리 만들기 - 2146
2+
3+
[문제 링크](https://www.acmicpc.net/problem/2146)
4+
5+
### 성능 요약
6+
7+
메모리: 74528 KB, 시간: 160 ms
8+
9+
### 분류
10+
11+
그래프 이론, 그래프 탐색, 너비 우선 탐색, 격자 그래프
12+
13+
### 제출 일자
14+
15+
2025년 8월 2일 11:22:20
16+
17+
### 문제 설명
18+
19+
<p>여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다는 생각을 하게 되었다. 그래서 그는, 생색내는 식으로 한 섬과 다른 섬을 잇는 다리 하나만을 만들기로 하였고, 그 또한 다리를 가장 짧게 하여 돈을 아끼려 하였다.</p>
20+
21+
<p>이 나라는 N×N크기의 이차원 평면상에 존재한다. 이 나라는 여러 섬으로 이루어져 있으며, 섬이란 동서남북으로 육지가 붙어있는 덩어리를 말한다. 다음은 세 개의 섬으로 이루어진 나라의 지도이다.</p>
22+
23+
<p style="text-align: center;"><img alt="" height="225" src="https://www.acmicpc.net/JudgeOnline/upload/201008/bri.PNG" width="243"></p>
24+
25+
<p>위의 그림에서 색이 있는 부분이 육지이고, 색이 없는 부분이 바다이다. 이 바다에 가장 짧은 다리를 놓아 두 대륙을 연결하고자 한다. 가장 짧은 다리란, 다리가 격자에서 차지하는 칸의 수가 가장 작은 다리를 말한다. 다음 그림에서 두 대륙을 연결하는 다리를 볼 수 있다.</p>
26+
27+
<p style="text-align: center;"><img alt="" height="220" src="https://www.acmicpc.net/JudgeOnline/upload/201008/b2.PNG" width="247"></p>
28+
29+
<p>물론 위의 방법 외에도 다리를 놓는 방법이 여러 가지 있으나, 위의 경우가 놓는 다리의 길이가 3으로 가장 짧다(물론 길이가 3인 다른 다리를 놓을 수 있는 방법도 몇 가지 있다).</p>
30+
31+
<p>지도가 주어질 때, 가장 짧은 다리 하나를 놓아 두 대륙을 연결하는 방법을 찾으시오.</p>
32+
33+
### 입력
34+
35+
<p>첫 줄에는 지도의 크기 N(100이하의 자연수)가 주어진다. 그 다음 N줄에는 N개의 숫자가 빈칸을 사이에 두고 주어지며, 0은 바다, 1은 육지를 나타낸다. 항상 두 개 이상의 섬이 있는 데이터만 입력으로 주어진다.</p>
36+
37+
### 출력
38+
39+
<p>첫째 줄에 가장 짧은 다리의 길이를 출력한다.</p>
40+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
class Main {
5+
static int N;
6+
static int[][] map;
7+
static int[][] island;
8+
static boolean[][][] visited;
9+
static int[] dx = {1, -1, 0, 0};
10+
static int[] dy = {0, 0, -1, 1};
11+
12+
public static void main(String[] args) throws Exception {
13+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
14+
N = Integer.parseInt(br.readLine());
15+
map = new int[N][N];
16+
island = new int[N][N];
17+
18+
for (int i = 0; i < N; i++) {
19+
StringTokenizer st = new StringTokenizer(br.readLine());
20+
for (int j = 0; j < N; j++) {
21+
map[i][j] = Integer.parseInt(st.nextToken());
22+
}
23+
}
24+
25+
int label = 0;
26+
for (int i = 0; i < N; i++) {
27+
for (int j = 0; j < N; j++) {
28+
if (map[i][j] == 1 && island[i][j] == 0) {
29+
label++;
30+
dfs(i, j, label);
31+
}
32+
}
33+
}
34+
35+
Queue<int[]> q = new ArrayDeque<>();
36+
visited = new boolean[label+1][N][N];
37+
38+
for (int i = 0; i < N; i++) {
39+
for (int j = 0; j < N; j++) {
40+
int lbl = island[i][j];
41+
if (lbl > 0) {
42+
for(int d = 0; d < 4; d++) {
43+
int ni = i + dx[d];
44+
int nj = j + dy[d];
45+
if (ni >= 0 && ni < N && nj >= 0 && nj < N && map[ni][nj] == 0) {
46+
visited[lbl][i][j] = true;
47+
q.offer(new int[]{i, j, lbl, 0});
48+
break;
49+
}
50+
}
51+
}
52+
}
53+
}
54+
55+
int ans = Integer.MAX_VALUE;
56+
while (!q.isEmpty()) {
57+
int[] cur = q.poll();
58+
int x = cur[0];
59+
int y = cur[1];
60+
int orig = cur[2];
61+
int dist = cur[3];
62+
63+
if (dist >= ans) continue;
64+
65+
for (int d = 0; d < 4; d++) {
66+
int nx = x + dx[d];
67+
int ny = y + dy[d];
68+
if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
69+
70+
if (!visited[orig][nx][ny]) {
71+
if (map[nx][ny] == 0) {
72+
visited[orig][nx][ny] = true;
73+
q.offer(new int[]{nx, ny, orig, dist + 1});
74+
}
75+
else if (island[nx][ny] != orig) {
76+
ans = Math.min(ans, dist);
77+
}
78+
}
79+
}
80+
}
81+
82+
System.out.println(ans);
83+
}
84+
85+
static void dfs(int i, int j, int label) {
86+
island[i][j] = label;
87+
for(int d = 0; d < 4; d++) {
88+
int ni = i + dx[d];
89+
int nj = j + dy[d];
90+
if (ni >= 0 && ni < N && nj >= 0 && nj < N) {
91+
if (map[ni][nj] == 1 && island[ni][nj] == 0) {
92+
dfs(ni, nj, label);
93+
}
94+
}
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)