다익스트라에서 선택해야할 우선순위 조건이 다음과 같이 2가지이다.
- 지나가는 쓰레기의 수는 최소로
- 쓰레기 근처를 지나는 칸의 수를 최소로
#include <bits/stdc++.h> using namespace std; #define INF 987654321 typedef pair<int, int> ii; typedef pair< ii, ii> pp; char s[50][51]; int h, w; int DX[] = {0, 0,-1, 1}; int DY[] = {1,-1, 0, 0}; bool aroundTrash(int y, int x){ for(int d=0; d<4; ++d){ int dy = y+DY[d], dx = x+DX[d]; if(dy < 0 || dx < 0 || dy >= h || dx >= w) continue; if(s[dy][dx] == 'g') return true; } return false; } ii reverse(const ii& p){ return {-p.first, -p.second}; } int main(){ int i, j; scanf("%d %d ", &h, &w); for(i=0; i<h; ++i) scanf("%s", s[i]); priority_queue<pp> pq; ii passed[51][51]; bool around[51][51]; int endY, endX; for(i=0; i<h; ++i){ for(j=0; j<w; ++j){ passed[i][j] = {INF, INF}; if(s[i][j] == 'S') pq.push({{0, 0}, {i, j}}); else if(s[i][j] == 'F'){ endY = i; endX = j; } around[i][j] = aroundTrash(i, j); } } while(!pq.empty()){ pp cur = pq.top(); pq.pop(); int pass = -cur.first.first; int arnd = -cur.first.second; int y = cur.second.first; int x = cur.second.second; if(passed[y][x] < reverse(cur.first)) continue; passed[y][x] = reverse(cur.first); if(s[y][x] == 'F') break; for(i=0; i<4; ++i){ int dy = y+DY[i], dx = x+DX[i]; if(dy < 0 || dx < 0 || dy >= h || dx >= w) continue; ii next = {pass, arnd}; if(s[dy][dx]=='g') next = {pass + 1, arnd}; if(s[dy][dx]=='.') next = {pass, arnd + around[dy][dx]}; if(passed[dy][dx] <= next) continue; passed[dy][dx] = next; pq.push({reverse(next), {dy, dx}}); } } printf("%d %d", passed[endY][endX].first, passed[endY][endX].second); return 0; }
댓글 없음:
댓글 쓰기