2차원 평면에서 큐를 넣고 빼고 하는 코드를 적으면 왠지 귀찮을꺼같아서 각 칸을 노드처럼 썼다. 예를 들면, 각 칸의 노드 번호는 아래와 같다.
// 4x2 크기의 평면1인 칸으로 가는 경우에는 벽을 부숴야하므로 가중치가 1인 간선이 있다고 생각하면 된다. (그 외에는 가중치가 0인 간선)
0123
4567
그럼 다익스트라로 0번 -> h*w-1번 으로 가는 최단 경로 문제가 된다.
같이 보기
- 알고스팟: BOJ#include <bits/stdc++.h>
using namespace std;
#define INF 987654321
typedef pair<int, int> ii;
int dijkstra(vector<ii> adj[], int n, int s, int e){
vector<int> cost(n, INF); /* s 로부터 i까지의 최소 비용 */
priority_queue<ii /*(-weight, next)*/> q;
q.push({0, s});
cost[s] = 0;
while(!q.empty()){
int pos = q.top().second;
int dist = -q.top().first;
q.pop();
for(int i=0; i<adj[pos].size(); ++i){
ii& next = adj[pos][i]; /* (next, weight) */
if(dist + next.second >= cost[next.first]) continue;
q.push({-(dist+next.second), next.first});
cost[next.first] = dist+next.second;
}
}
return cost[e];
}
int h, w;
int DX[] = {0, 0,-1, 1};
int DY[] = {1,-1, 0, 0};
int nodeNumber(int y, int x){
return y*w + x;
}
int main(){
int i, j;
scanf("%d %d ", &w, &h);
char s[100][101];
for(i=0; i<h; ++i) scanf("%s", s[i]);
int nodes = h*w;
vector<ii> adj[nodes];
for(i=0; i<h; ++i){
for(j=0; j<w; ++j){
for(int d=0; d<4; ++d){
int dy = i+DY[d], dx = j+DX[d];
if(dy < 0 || dx < 0 || dy >= h || dx >= w) continue;
adj[nodeNumber(i, j)].push_back({nodeNumber(dy, dx), s[dy][dx]=='1'});
adj[nodeNumber(dy, dx)].push_back({nodeNumber(i, j), s[i][j]=='1'});
}
}
}
printf("%d", dijkstra(adj, nodes, 0, nodes-1));
return 0;
}
댓글 없음:
댓글 쓰기