-
[백준 2665] 미로 만들기백준/다익스트라 2025. 9. 24. 01:41
이 문제는 2차원 배열때문에 BFS처럼 보일 수 있지만
문제의 목적이 최단경로를 찾는 것이 아니기 때문에 BFS로 풀면 안된다.
최소로 벽을 뚫으면서 목적지까지 가는 것이기 때문에
벽 뚫는 횟수를 기준으로 한 그리디적인 접근으로 풀어야한다.
그래서 다익스트라를 써야하고 목적지가 오른쪽 아래에 있다고 아래와 오른쪽 방향만 신경쓰면 안된다.
위로 가면서 벽을 덜 뚫는 루트가 있을 수 있기 때문
#include <iostream> #include <bitset> #include <queue> #include <tuple> #define SIZE 51 #define INF int(1e9) using namespace std; int N; bitset<SIZE> map[SIZE]; // 최단경로가 아님. 벽을 최소로 뚫는 것이기 때문에 목적지가 오른쪽 끝에 있다고 왼쪽으로 움직이는 것을 배제하면 안됨! int dy[4] = {-1, 1, 0, 0}; int dx[4] = {0, 0, -1, 1}; bool is_available(int y, int x) { if (y < 1 || x < 1 || y > N || x > N) { return false; } return true; } int memo[SIZE][SIZE]; void solve() { priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq; pq.push({0, 1, 1}); memo[1][1] = 0; int nexty, nextx; while (!pq.empty()) { auto [cnt, y, x] = pq.top(); pq.pop(); for (int i = 0; i < 4; i++) { nexty = y + dy[i]; nextx = x + dx[i]; if (!is_available(nexty, nextx)) { continue; } // 벽이라면 if (map[nexty][nextx] == 0) { if (cnt + 1 < memo[nexty][nextx]) { memo[nexty][nextx] = cnt + 1; pq.push({cnt + 1, nexty, nextx}); } } // 벽이 아니면 else { if (cnt < memo[nexty][nextx]) { memo[nexty][nextx] = cnt; pq.push({cnt, nexty, nextx}); } } } } } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N; for (int i = 1; i <= N; i++) { for (int k = 1; k <= N; k++) { memo[i][k] = INF; } } char ch; for (int i = 1; i <= N; i++) { for (int k = 1; k <= N; k++) { cin >> ch; if (ch == '0') { map[i][k] = 0; } else { map[i][k] = 1; } } } solve(); // for (int i = 1; i <= N; i++) // { // for (int k = 1; k <= N; k++) // { // cout << memo[i][k] << " "; // } // cout << "\n"; // } cout << memo[N][N]; return 0; }'백준 > 다익스트라' 카테고리의 다른 글
[백준 4485] 녹색 옷 입은 애가 젤다 (1) 2025.10.10 [백준 17835] 면접보는 승범이네 (0) 2025.10.06 [백준 13911] 집 구하기 (0) 2025.09.14 [백준 1967] 트리의 지름 (0) 2025.09.13 [백준 13609] 세금 (0) 2025.09.07