일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- dfs
- 비트마스크
- 펜윅트리
- 구현
- DisjointSet
- MST
- 이진탐색
- 플로이드와샬
- 수학
- 브루트포스
- 정렬
- 그리디
- 위상정렬
- 이분탐색
- BFS
- 삼분탐색
- lis
- lca
- 크루스칼
- boj
- LazyPropagation
- 이분매칭
- DP
- 에라토스테네스의 체
- 좌표압축
- 세그먼트트리
- 다익스트라
- 백준
- 누적합
- 투포인터
Archives
- Today
- Total
lastknight00
[백준]할로윈 묘지(3860) 본문
문제 링크 : [백준]할로윈 묘지(3860)
문제 설명
W * H 크기의 묘지가 있고, (0,0)에서 출발하여, 위, 아래, 왼쪽, 오른쪽 한 칸씩 이동하여, (W-1,H-1)까지 최단 시간에 이동하려고 합니다.
묘지에는 묘비들이 있는데, 이 묘비가 있는 곳으로는 가지 못합니다.
또 귀신 구멍이 있어, 귀신 구멍 입구로 들어가게 되면 귀신 구멍 출구로 나가게 되는데 이때 걸리는 시간은 임의의 음수 혹은 임의의 양수가 될 수 있습니다.
최소 시간을 출력하며, 계속 과거로 돌아갈 수 있으면 "Never", 갈 수 없으면 "Impossible" 을 출력합니다.
입력
W H(묘지의 가로, 세로 크기, 1 <= W, H <= 30)
G(묘비의 갯수)
Xi Yi(묘비의 위치)
E(귀신 구멍의 갯수)
X1i Y1i X2i Y2i Ci(귀신 구멍의 입구, 출구 위치와 걸리는 시간)
3 3
2
2 1
1 2
0
4 3
2
2 1
3 1
1
3 0 2 2 0
4 2
0
1
2 0 1 0 -3
0 0
출력
Impossible
4
Never
카테고리
#벨만포드
시간 복잡도 상한
O(N5)
해결 방법
- 간선 정보는 인접한 칸들의 좌표들로 생성하며, 묘비와 귀신 구멍들의 정보들과 조합하여 필요한 모든 엣지들을 구성합니다.
- 음수 싸이클이 존재하는 경우, Never를 출력해야하기 때문에 음수 싸이클을 확인 할 수 있는 벨만포드를 이용합니다.
- 벨만포드를 통하여 도착지까지의 최단 거리를 구하고, 이동 중 음수 싸이클이 발생하였는지를 검사합니다.
시간복잡도
O(N4)(N2 : 간선의 갯수, N2 : 노드의 갯수)
코드
#include<cstdio>
#include<string.h>
#include<vector>
#define D 1e9
using namespace std;
int n,m,g,x,y,a,b,c,d[31][31],w[31][31],o[4][2]={{1,0},{0,1},{-1,0},{0,-1}},i;
struct N{
N(int x,int y,int a,int b,int c):x(x),y(y),a(a),b(b),c(c){}
int x,y,a,b,c;
};
std::vector<N>v;
int main(){
while(1){
v.clear();
memset(w,0,sizeof(w));
for(x=0;x<31;x++)for(y=0;y<31;y++)d[x][y]=D;
scanf("%d%d",&m,&n);
if(!n)break;
scanf("%d",&g);
while(g--)scanf("%d%d",&x,&y),w[x][y]=1;
scanf("%d",&g);
while(g--){
scanf("%d%d%d%d%d",&x,&y,&a,&b,&c);
v.push_back(N(x,y,a,b,c));
w[x][y]=-1;
}
for(x=0;x<m;x++){
for(y=0;y<n;y++){
if((x==m-1&&y==n-1)||w[x][y])continue;
for(a=0;a<4;a++){
int nx=x+o[a][0],ny=y+o[a][1];
if(nx>=0&&nx<m&&ny>=0&&ny<n&&w[nx][ny]<1)v.push_back(N(x,y,nx,ny,1));
}
}
}
d[0][0]=0;
for(c=g=1;g<=n*m;g++){
for(N b:v){
if(d[b.x][b.y]<D&&d[b.a][b.b]>d[b.x][b.y]+b.c){
d[b.a][b.b]=d[b.x][b.y]+b.c;
if(g==n*m)c=0;
}
}
}
if(!c)printf("Never\n");
else if(d[m-1][n-1]<D)printf("%d\n",d[m-1][n-1]);
else printf("Impossible\n");
}
}
'PS' 카테고리의 다른 글
[백준]K번째 최단경로 찾기(1854) (0) | 2020.08.16 |
---|---|
[백준]거의 최단 경로(5719) (0) | 2020.08.16 |
[백준]도로 네트워크(3176) (0) | 2020.08.15 |
[백준]줄 세우기(2252) (0) | 2020.08.15 |
[백준]게임 개발(1516) (0) | 2020.08.08 |
Comments