250x250
Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 목표 및 회고
- 프래그먼트
- 안드로이드 Sunflower 스터디
- 주택가 잠실새내
- 막내의막무가내 코틀린 안드로이드
- 부스트코스에이스
- 프로그래머스 알고리즘
- 부스트코스
- 막내의막무가내 플러터
- 막내의막무가내 안드로이드
- 막내의 막무가내 알고리즘
- 막무가내
- 막내의 막무가내
- 막내의막무가내
- 안드로이드
- 막내의막무가내 코틀린
- 주엽역 생활맥주
- 막내의막무가내 플러터 flutter
- 2022년 6월 일상
- 막내의막무가내 SQL
- 막내의막무가내 rxjava
- Fragment
- 막내의막무가내 안드로이드 에러 해결
- 막내의막무가내 일상
- flutter network call
- 안드로이드 sunflower
- 막내의막무가내 프로그래밍
- 막내의막무가내 알고리즘
- 막내의막무가내 안드로이드 코틀린
Archives
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[알고리즘] 백준 2146 다리만들기 -BFS- 자바 본문
728x90
백준 BFS 유형의 백준 2146 다리만들기 문제입니다.
여러개의 섬이(1) 있는데 바다에(0) 최소의 다리 개수를 설치하여 여러개의 섬들 중 두 개의 섬을 이을 수 있게 하려는 문제 입니다.
BFS를 살짝 응용한 문제입니다. 처음에 너무 비효율적으로 자원을 소비하는건가 했는데 통과되었습니다.
풀이를 간략히 설명하면,
1. 섬마다 번호가 똑같으므로 바로 BFS로 다른 섬을 찾아 연결하기가 힘듭니다. 그러므로 섬에 각각 다른 번호이름을 붙여주도록 합니다.
2. 이제 섬마다 BFS를 하여 다른 섬과 다리를 설치할 수 있는 경우의 수를 찾도록 합니다. 그리고 다리를 최소의 개수로 설치한 경우를 업데이트 해줍니다.
풀이는 다음과 같습니다.
[Java]
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class Main {
private static int[][] map;
private static boolean[][] isVisited;
private static int N;
private static int[] dr = new int[]{-1, 0, 1, 0};
private static int[] dc = new int[]{0, -1, 0, 1};
private static int landNum = 2; //섬 번호이름
private static int answer = Integer.MAX_VALUE; //답
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
map = new int[N][N];
isVisited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
map[i][j] = sc.nextInt();
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (map[r][c] == 1) { // 아직 번호이름 없는 섬인 경우
makeLand(r, c);
}
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (map[r][c] >= 2) {
isVisited = new boolean[N][N]; //재초기화
bfs(r, c);
}
}
}
System.out.println(answer);
}
// 섬 별로 번호이름 붙여주기
private static void makeLand(int r, int c) {
Queue<Point> queue = new LinkedList<>();
queue.offer(new Point(r, c, 0));
isVisited[r][c] = true;
map[r][c] = landNum;
while (!queue.isEmpty()) {
Point point = queue.poll();
for (int i = 0; i < 4; i++) {
int r2 = point.r + dr[i];
int c2 = point.c + dc[i];
if ((r2 >= 0 && r2 < N && c2 >= 0 && c2 < N) && !isVisited[r2][c2] && map[r2][c2] == 1) {
isVisited[r2][c2] = true;
map[r2][c2] = landNum;
queue.offer(new Point(r2, c2, 0));
}
}
}
landNum++;
}
private static void bfs(int r, int c) {
Queue<Point> queue = new LinkedList<Point>();
queue.offer(new Point(r, c, 0));
int currentLandNum = map[r][c];// 현재 섬 번호
isVisited[r][c] = true;
while (!queue.isEmpty()) {
Point point = queue.poll();
for (int i = 0; i < 4; i++) {
int r2 = point.r + dr[i];
int c2 = point.c + dc[i];
if ((r2 >= 0 && r2 < N && c2 >= 0 && c2 < N) && !isVisited[r2][c2] && map[r2][c2] != currentLandNum) { //방문안하고 바다 혹은 다른 섬인 경우
isVisited[r2][c2] = true;
if (map[r2][c2] == 0) { //바다
queue.offer(new Point(r2, c2, point.cnt + 1));
} else { //다른 섬
answer = Math.min(answer, point.cnt);
}
}
}
}
}
static class Point {
int r;
int c;
int cnt;
public Point(int r, int c, int cnt) {
this.r = r;
this.c = c;
this.cnt = cnt;
}
}
}
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!
728x90
'알고리즘 > DFS, BFS, 시뮬, 백트래킹' 카테고리의 다른 글
[알고리즘] 기출문제 -dfs, 백트랙킹- (0) | 2021.03.23 |
---|---|
[알고리즘] 백준 1182 부분수열의 합 -백트랙킹, 그리디- 자바 (0) | 2021.03.22 |
[알고리즘] 백준 2468 안전영역 -BFS- 자바 (2) | 2021.02.28 |
[알고리즘] 백준 2023 신기한 소수 -백트랙킹- 자바 코틀린 (2) | 2021.02.21 |
[알고리즘] 프로그래머스 가장 먼 노드 -그래프- 자바 (0) | 2021.01.02 |
Comments