728x90
반응형
https://www.acmicpc.net/problem/3860
이 문제는 음수 간선이 포함되어져 있는 그래프의 최단거리를 구하는 문제입니다.
벨만포드를 활용해서 풀이가 가능하나, 저는 spfa(Short path fast algorithm)이라는 알고리즘을 활용하여 해당 문제를 해결하였습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int n, m;
static ArrayList<Node>[][] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 1<<16);
StringBuilder sb = new StringBuilder();
while(true) {
System.gc();
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
if(n == 0 && m == 0) {
break;
}
boolean[][] stone = new boolean[31][31];
arr = new ArrayList[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
arr[i][j] = new ArrayList<>(4);
}
}
int g = Integer.parseInt(br.readLine());
while(g --> 0) {
st = new StringTokenizer(br.readLine());
stone[Integer.parseInt(st.nextToken())][Integer.parseInt(st.nextToken())] = true;
}
int e = Integer.parseInt(br.readLine());
while(e --> 0) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()), b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken()), d = Integer.parseInt(st.nextToken());
int val = Integer.parseInt(st.nextToken());
arr[a][b].add(new Node(c, d, val));
}
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(arr[i][j].size() != 0 || stone[i][j] || (i == n -1 && j == m - 1)) {
continue;
}
for(int k = 0; k < 4; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if(nx >= 0 && nx < n && ny >= 0 && ny < m && !stone[nx][ny]) {
arr[i][j].add(new Node(nx, ny, 1));
}
}
}
}
sb.append(spfa()).append("\n");
}
System.out.print(sb);
}
public static String spfa() {
Queue<int[]> queue = new LinkedList<>();
boolean[][] visited = new boolean[n][m];
long[][] dist = new long[n][m];
int[][] cycle = new int[n][m];
for(int i = 0; i < n; i++) {
Arrays.fill(dist[i], (long)1e18);
}
queue.add(new int[] {0, 0});
dist[0][0] = 0;
cycle[0][0]++;
visited[0][0] = true;
while(!queue.isEmpty()) {
int[] now = queue.poll();
int x = now[0], y = now[1];
visited[x][y] = false;
for(Node a : arr[x][y]) {
if(dist[a.x][a.y] > dist[x][y] + a.cost) {
dist[a.x][a.y] = dist[x][y] + a.cost;
if(!visited[a.x][a.y]) {
cycle[a.x][a.y]++;
if(cycle[a.x][a.y] >= n * m) {
return "Never";
}
queue.add(new int[] {a.x, a.y});
visited[a.x][a.y] = true;
}
}
}
}
return dist[n - 1][m - 1] == (long)1e18 ? "Impossible" : dist[n - 1][m - 1] + "";
}
}
class Node{
int x, y, cost;
public Node(int x, int y, int cost) {
this.x = x;
this.y = y;
this.cost = cost;
}
}728x90
반응형
'백준 > 1 - 5000' 카테고리의 다른 글
| [백준] 2180번 : 소방서의 고민 (0) | 2025.11.02 |
|---|---|
| [백준] 1854번 : K번째 최단경로 찾기 (0) | 2025.10.12 |
| [백준] 2150번 : Strongly Connected Componen (0) | 2025.08.17 |
| [백준] 2325번 : 개코전쟁 (0) | 2024.12.08 |
| [백준] 2123번 : 인간 탑 쌓기 (0) | 2024.11.17 |
댓글