어흥

[백준 3860] 할로윈 묘지 (C++) 본문

알고리즘/백준

[백준 3860] 할로윈 묘지 (C++)

라이언납시오 2020. 5. 1. 17:54
728x90
반응형

문제 링크: https://www.acmicpc.net/problem/3860

 

3860번: 할로윈 묘지

문제 오늘은 할로윈이다. 상근이와 친구들은 할로윈을 기념하기 위해 묘지를 방문했다. 상근이와 친구들은 한 명씩 묘지로 들어가고, 혼자서 묘지의 출구를 찾아야 한다. 이제, 상근이의 차례가 돌아왔다. 상근이가 어렸을 적에 할머니는 상근이에게 할로윈 밤에 묘지에는 귀신 구멍이 나타난다고 말해주었다. 귀신 구멍으로 들어가면, 묘지의 다른 장소로 다시 나오게 된다. 이 구멍은 시간을 이동할 수 있는 구멍이다. 귀신 구멍에 떨어지면, 특정 시간이 지난 후(또는 이

www.acmicpc.net

1. 주의할 점

- 매 TC마다 초기화 필수

- 도착지점에서 뻗어나가는 간선은 존재하면 안된다

- 간선형태로 정보를 저장한다 (Y좌표 * 너비 + X좌표)

 

2. 구현

- 묘비의 위치에는 Arr[][]배열에서 -1을 저장한다

- Make_graph() 함수를 통해 일반적인 이동의 경우 그래프에 추가한다

- Bellman_ford() 함수를 통해 Dist[]를 계속 Row*Col번 갱신하며, Row*Col번 일때 Dist[]가 갱신된다면 음의 값을 가지는 순환 사이클이 있다고 판단하여 Never를 출력하도록 한다 

 

#define MAX 987654321
#include <iostream>
#include <vector>
using namespace std;
struct info {
	int to,val;
};
info tmp;
int row, col, tomb, tx, ty, hole, ex, ey, ax, ay, t;
int arr[31][31];
bool ghost[31][31];
bool cycle;
int dx[4] = { 0,1,0,-1 };
int dy[4] = { -1,0,1,0 };
vector<info> v[901];		//row*col+col
int dist[901];

void make_graph() {
	//한 노드에서 다른 노드로 갈 수 있는 경우 v[]에 추가
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			if (arr[i][j] == -1 || (i*col+j==row*col-1) || ghost[i][j]) continue;
			for (int k = 0; k < 4; k++) {
				int nx = j + dx[k];
				int ny = i + dy[k];
				if (nx >= 0 && ny >= 0 && nx < col && ny < row && arr[ny][nx] != -1) {
					int a = i * col + j;
					int b = ny * col + nx;
					tmp.to = b;
					tmp.val = 1;
					v[a].push_back(tmp);
				}
			}
		}
	}
}

void bellman_ford() {
	//Node의 수+1 만큼 수행
	for (int i = 0; i <= row * col; i++) {
		for (int j = 0; j < row * col; j++) {
			if (dist[j] == MAX) continue;
			for (int k = 0; k < v[j].size(); k++) {
				int to = v[j][k].to;
				int val = v[j][k].val;
				int d = dist[j] + val;
				if (d != MAX && dist[to] > d) {
					if (i == (row * col)) 	cycle = true;					
					dist[to] = d;
				}
			}
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	while (1) {
		cin >> col >> row;
		if (row == 0 && col == 0) break;			
		//초기화
		for (int i = 0; i < row; i++)
			for (int j = 0; j < col; j++) {
				ghost[i][j] = false;
				arr[i][j] = 0;
			}
		cycle = false;
		for (int i = 0; i <= row * col; i++) {
			dist[i] = MAX;
			v[i].clear();
		}
		dist[0] = 0;

		cin >> tomb;
		for (int i = 0; i < tomb; i++) {
			cin >> tx >> ty;
			arr[ty][tx] = -1;
		}
		cin >> hole;
		for (int i = 0; i < hole; i++) {
			cin >> ex >> ey >> ax >> ay >> t;
			int a = ey * col + ex;
			int b = ay * col + ax;
			tmp.to = b;
			tmp.val = t;
			v[a].push_back(tmp);
			ghost[ey][ex] = true;
		}
		make_graph();
		bellman_ford();
		if (cycle) cout << "Never\n";
		else if (dist[row*col-1] == MAX) cout << "Impossible\n";
		else cout << dist[row*col - 1] << '\n';
	}
	system("pause");
	return 0;
}
728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 11657] 타임머신 (C++)  (0) 2020.05.03
[백준 2887] 행성 터널 (C++)  (0) 2020.05.02
[백준 1248] 맞춰봐 (C++)  (0) 2020.04.29
[백준 1400] 화물차 (C++)  (0) 2020.04.28
[백준 8452] 그래프와 쿼리 (C++)  (0) 2020.04.27
Comments