https://www.acmicpc.net/problem/1261
1. 아이디어
다익스트라 알고리즘 또는 0-1 BFS 알고리즘으로 해결할 수 있다.
2. 문제풀이
(1, 1)에서 (N, M)까지 벽을 최소한으로 부수면서 이동해야 하는 문제로 벽이 있는 칸을 가중치 1인 간선으로 이동, 벽이 없는 칸은 가중치 0인 간선으로 이동이라고 했을 때 0과 1의 가중치를 갖는 간선으로 이루어진 그래프에서 최단 경로로 이동하는 문제가 된다. 이는 다익스트라 알고리즘으로 해결할 수 있고 가중치가 0과 1 두가지만 있는 경우 Deque 자료구조를 활용한 0-1 BFS 알고리즘으로도 해결할 수 있다. 두 가지 모두 간단하게 구현만하면 해결할 수 있다.
3. 코드
import java.io.*;
import java.util.*;
public class Main_BFS01 {
private static class Node {
int r;
int c;
public Node(int r, int c) {
this.r = r;
this.c = c;
}
}
private static final int[] dr = {-1, 0, 1, 0};
private static final int[] dc = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int M = Integer.parseInt(st.nextToken());
int N = Integer.parseInt(st.nextToken());
char[][] map = new char[N][M];
for (int i = 0; i < N; i++) {
map[i] = br.readLine().toCharArray();
}
int dist = zero_one_bfs(N, M, map);
System.out.println(dist);
}
// 0-1 BFS 알고리즘
private static int zero_one_bfs(int N, int M, char[][] map) {
Deque<Node> dq = new ArrayDeque<>();
dq.add(new Node(0, 0));
boolean[][] visited = new boolean[N][M];
visited[0][0] = true;
int dist = 0;
while (!dq.isEmpty()) {
int len = dq.size();
for (int i = 0; i < len; i++) {
Node node = dq.removeFirst();
if (node.r == N - 1 && node.c == M - 1) return dist;
for (int dir = 0; dir < 4; dir++) {
int nr = node.r + dr[dir];
int nc = node.c + dc[dir];
if (nr < 0 || nr >= N || nc < 0 || nc >= M) continue;
if (visited[nr][nc]) continue;
if (map[nr][nc] == '0') {
dq.addFirst(new Node(nr, nc));
visited[nr][nc] = true;
i--;
} else {
dq.addLast(new Node(nr, nc));
visited[nr][nc] = true;
}
}
}
dist++;
}
return -1;
}
}
import java.io.*;
import java.util.*;
public class Main_Dijkstra {
private static class Node implements Comparable<Node> {
int r;
int c;
int dist;
public Node(int r, int c, int dist) {
this.r = r;
this.c = c;
this.dist = dist;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.dist, o.dist);
}
}
private static final int INF = 1_000_000_000;
private static final int[] dr = {-1, 0, 1, 0};
private static final int[] dc = {0, 1, 0, -1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int M = Integer.parseInt(st.nextToken());
int N = Integer.parseInt(st.nextToken());
char[][] map = new char[N][M];
for (int i = 0; i < N; i++) {
map[i] = br.readLine().toCharArray();
}
int dist = dijkstra(N, M, map);
System.out.println(dist);
}
// 다익스트라 알고리즘
private static int dijkstra(int N, int M, char[][] map) {
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(0, 0, 0));
boolean[][] visited = new boolean[N][M];
int[][] dist = new int[N][M];
for (int i = 0; i < N; i++) {
Arrays.fill(dist[i], INF);
}
dist[0][0] = 0;
while (!pq.isEmpty()) {
Node node = pq.remove();
if (node.r == N - 1 && node.c == M - 1) return node.dist;
if (visited[node.r][node.c]) continue;
visited[node.r][node.c] = true;
for (int dir = 0; dir < 4; dir++) {
int nr = node.r + dr[dir];
int nc = node.c + dc[dir];
if (nr < 0 || nr >= N || nc < 0 || nc >= M) continue;
if (visited[nr][nc]) continue;
if (map[nr][nc] == '0') {
if (dist[nr][nc] > dist[node.r][node.c]) {
dist[nr][nc] = dist[node.r][node.c];
pq.add(new Node(nr, nc, dist[nr][nc]));
}
} else {
if (dist[nr][nc] > dist[node.r][node.c] + 1) {
dist[nr][nc] = dist[node.r][node.c] + 1;
pq.add(new Node(nr, nc, dist[nr][nc]));
}
}
}
}
return -1;
}
}
4. 후기
- 0-1 BFS 알고리즘
- 다익스트라 알고리즘
'코딩테스트 준비 > 백준' 카테고리의 다른 글
[백준] 14497번 - 주난의 난(難) [Java] (0) | 2025.02.01 |
---|---|
[백준] 2665번 - 미로만들기 [Java] (0) | 2025.02.01 |
[백준] 1254번 - 팰린드롬 만들기 [Java] (0) | 2025.02.01 |
[백준] 25426번 - 일차함수들 [Java] (0) | 2025.02.01 |
[백준] 10826번 - 피보나치 수 4 [Java] (0) | 2025.02.01 |