[SWEA] 1249. 보급로 (C++, 라이브러리 X)
Algorithm 카테고리의 다른 글
Heap 기본문제
풀이
복구 시간을 기준으로 Min Heap을 만듦.
복구 시간이 최소인 지점(Pop)에서 상하좌우로 이동했을 경우 좌표와 복구 시간을 Min Heap에 넣어줌(Add)
이렇게 되면 복구 시간이 최소인 지점이 N-1, N-1 일때 복구 시간이 정답이 됨.
추가로, 최소 복구 시간으로 한번 탐색했던 지점은 체크하여 다시 탐색하지 않도록 함.
코드 GitHub
#include <iostream>
using namespace std;
const int dr[4] = {0, 0, -1, 1};
const int dc[4] = {-1, 1, 0, 0};
#define MAXN 100
int map[MAXN][MAXN];
int N;
struct Node {
int recovery;
int r, c;
} nodes[MAXN * MAXN];
int nodeCnt;
bool check[MAXN][MAXN];
bool CmpSwap(int idxA, int idxB) {
if(nodes[idxA].recovery > nodes[idxB].recovery) {
Node tmp = nodes[idxA];
nodes[idxA] = nodes[idxB];
nodes[idxB] = tmp;
return true;
} else return false;
}
void Init() {
nodeCnt = 0;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
check[i][j] = false;
}
}
return;
}
void Add(int rec, int r, int c) {
if(check[r][c]) return;
nodes[nodeCnt].recovery = rec;
nodes[nodeCnt].r = r;
nodes[nodeCnt].c = c;
int pivot = nodeCnt;
nodeCnt++;
while(pivot > 0) {
int ppivot = pivot;
pivot = (pivot - 1) >> 1;
if(!CmpSwap(pivot, ppivot)) break;
}
return;
}
Node Pop() {
Node rev = nodes[0];
check[rev.r][rev.c] = true;
nodes[0] = nodes[--nodeCnt];
int pivot = 0;
while(true) {
int ppivot = pivot;
pivot = (pivot << 1) + 1;
if(pivot >= nodeCnt) break;
else if(pivot + 1 == nodeCnt) {
if(!CmpSwap(ppivot, pivot)) break;
} else {
if(nodes[pivot].recovery > nodes[pivot + 1].recovery) pivot++;
if(!CmpSwap(ppivot, pivot)) break;
}
}
return rev;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
freopen("input.txt", "r", stdin);
int T;
cin >> T;
for(int tc = 1; tc <= T; tc++) {
cin >> N;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
char a;
cin >> a;
map[i][j] = a - '0';
}
}
Init();
Add(0, 0, 0);
int ans;
while(nodeCnt > 0) {
Node node = Pop();
if(node.r == N - 1 && node.c == N -1) {
ans = node.recovery;
break;
}
for(int i = 0; i < 4; i++) {
int nr = node.r + dr[i];
int nc = node.c + dc[i];
if(nr < 0 || nr >= N || nc < 0 || nc >= N) continue;
int nrec = node.recovery + map[nr][nc];
Add(nrec, nr, nc);
}
}
cout << '#' << tc << ' ' << ans << '\n';
}
return 0;
}
댓글남기기