[백준/BOJ] 백준 3860번 : 할로윈 묘지
2020. 12. 30. 02:58ㆍ알고리즘 문제풀이
3860번: 할로윈 묘지
오늘은 할로윈이다. 상근이와 친구들은 할로윈을 기념하기 위해 묘지를 방문했다. 상근이와 친구들은 한 명씩 묘지로 들어가고, 혼자서 묘지의 출구를 찾아야 한다. 이제, 상근이의 차례가 돌아
www.acmicpc.net
그래프를 만들고 벨만 포드 알고리즘을 이용해 문제를 해결했다. 벨만 포드 알고리즘에서 here이 묘비인 경우와, here로 아직 오는 방법이 없을 때를 고려한다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
int w, h;
int g;
int e;
vector<pair<int, pair<int, int>>> adj[30][30]; //걸리는 시간과 위치
int dxdy[4][2] = { {0,-1},{-1,0},{0,1},{1,0} };
int check_g_stone[30][30];
int node_num;
void Pre()
{
for (int i = 0; i < 30; i++)
for (int j = 0; j < 30; j++)
{
adj[i][j].clear();
check_g_stone[i][j] = 0;
}
}
//그래프 만들기
void Make_adj()
{
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
pair<int, int> here = make_pair(i, j);
//here이 묘비일때
if (check_g_stone[here.first][here.second] == 1)
continue;
//here이 출구일때
if (here.first == h - 1 && here.second == w - 1)
continue;
//접한 4곳을 그래프로 연결
for (int k = 0; k < 4; k++)
{
pair<int, int> there = make_pair(here.first + dxdy[k][0], here.second + dxdy[k][1]);
if (there.first >= 0 && there.first < h && there.second >= 0 && there.second < w)
{
if (check_g_stone[there.first][there.second] == 1) //there이 묘비일때
continue;
adj[here.first][here.second].push_back(make_pair(1, make_pair(there.first, there.second)));
}
}
}
}
//벨만포드 알고리즘 사용
int Solve(pair<int, int> start, pair<int, int> dest)
{
vector<vector<int>> upper(h, vector<int>(w, 987654321));
upper[start.first][start.second] = 0;
bool update;
for (int i = 0; i < node_num; i++)
{
update = false;
for (int j = 0; j < h; j++)
for (int k = 0; k < w; k++)
{
pair<int, int> here = make_pair(j, k);
if (check_g_stone[here.first][here.second] == 1)
continue;
if (upper[here.first][here.second] == 987654321) //아직 here에 오는 방법이 없을때
continue;
for (int l = 0; l < adj[here.first][here.second].size(); l++)
{
pair<int, int> there = adj[here.first][here.second][l].second;
int cost = adj[here.first][here.second][l].first;
if (upper[there.first][there.second] > upper[here.first][here.second] + cost)
{
upper[there.first][there.second] = upper[here.first][here.second] + cost;
update = true;
}
}
}
if (update == false)
break;
}
if (update == true)
return -987654321;
return upper[dest.first][dest.second];
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
while (1)
{
Pre();
cin >> w >> h;
if (w == 0 && h == 0)
break;
node_num = w * h;
cin >> g;
node_num -= g;
for (int i = 0; i < g; i++)
{
int x, y;
cin >> x >> y;
check_g_stone[y][x] = 1;
}
Make_adj();
cin >> e;
for (int i = 0; i < e; i++) //귀신 구멍 부분은 이전에 만든 그래프에서 수정
{
int x1, y1, x2, y2, t;
cin >> x1 >> y1 >> x2 >> y2 >> t;
adj[y1][x1].clear(); //이전에 만든것 삭제
adj[y1][x1].push_back(make_pair(t, make_pair(y2, x2)));
}
int result = Solve(make_pair(0, 0), make_pair(h - 1, w - 1));
if (result == -987654321)
cout << "Never" << "\n";
else if (result == 987654321)
cout << "Impossible" << "\n";
else
cout << result << "\n";
}
return 0;
}
'알고리즘 문제풀이' 카테고리의 다른 글
[백준/BOJ] 백준 2042번 : 구간 합 구하기 (0) | 2020.12.30 |
---|---|
[백준/BOJ] 백준 1602번 : 도망자 원숭이 (0) | 2020.12.30 |
[백준/BOJ] 백준 11437번 : LCA (0) | 2020.12.30 |
[백준/BOJ] 백준 12849번 : 본대 산책 (0) | 2020.12.30 |
[백준/BOJ] 백준 14003번 : 가장 긴 증가하는 부분 수열 5 (0) | 2020.12.29 |