문제
https://www.acmicpc.net/problem/1261
1261번: 알고스팟
첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미
www.acmicpc.net
문제 요약
N × M 크기의 미로에서 (1, 1)에서 출발해 (N, M)까지 가기 위해 벽을 최소 몇 개 부수어야하는지 출력한다.
어떤 방에서 이동할 수 있는 방은 상하좌우로 인접한 빈 방이다.
코드
#include<iostream>
#include<queue>
#include<algorithm>
#include<tuple>
using namespace std;
#define MAX 100
int n, m;
int board[MAX][MAX];
int dist[MAX][MAX]; // (0, 0)에서 (i, j)까지 이동하는데 제거해야하는 1의 최소 개수
bool visit[MAX][MAX];
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
queue<tuple<int, int>> q;
int res = 1e9;
int cnt;
void dijstra() {
visit[0][0] = true;
dist[0][0] = 0;
q.push({ 0, 0 });
while (!q.empty()) {
int x, y;
tie(x, y) = q.front();
q.pop();
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (board[nx][ny] == 1) {
if (dist[nx][ny] > dist[x][y] + 1) { // 아직 dist[nx][ny]가 최소가 아닐 때
dist[nx][ny] = dist[x][y] + 1;
q.push({ nx, ny }); // 주변 노드도 새롭게 갱신
}
}
else {
if (dist[nx][ny] > dist[x][y]) {
dist[nx][ny] = dist[x][y];
q.push({ nx, ny });
}
}
}
}
}
int main() {
cin >> m >> n;
//cout << "check";
string str;
for (int i = 0; i < n; i++) {
cin >> str;
for (int j = 0; j < m; j++) {
board[i][j] = str[j] - '0';
dist[i][j] = 1e9;
}
}
dijstra();
cout << dist[n - 1][m - 1];
return 0;
}
코드 설명
1. 미로의 크기 정보와, 각 칸의 빈 방 여부를 입력 받는다.
2. 다익스트라 알고리즘을 이용해 (1, 1)부터 각 칸까지 벽을 최소 몇 개를 부수어야 도착하는지 dist 배열에 저장한다.
2 - 1. 각 칸을 방문할 때, 빈 방인지, 벽이 존재하는지에 따라 나눠 dist를 갱신한다.
2 - 2. 벽이 존재한다면, 해당 칸의 벽을 부수어야하므로, 이전 dist + 1과 비교하여 작은 값으로 갱신한다.
2 - 3. 빈 방이라면, 이전 칸에서 벽을 부수지 않고 이동할 수 있으므로, dist와 비교하여 작은 값으로 갱신한다.
2 - 4. 해당 칸이 갱신되었다면, 큐에 인덱스 정보를 넣어 주변 칸의 dist도 갱신한다.
3. dist[n-1][m-1]을 출력한다.
'Algorithm Problems > 그래프' 카테고리의 다른 글
[백준/C++] 1504번: 특정한 최단 경로 (2) | 2024.02.09 |
---|---|
[백준/C++] 1967번: 트리의 지름 (2) | 2024.02.08 |
[백준/C++] 14267번: 회사 문화 1 (0) | 2024.01.16 |
[백준/C++] 4963번: 섬의 개수 (0) | 2024.01.11 |
[백준/Python] 24230번: 트리 색칠하기 (1) | 2024.01.08 |