PS/BOJ2022. 5. 4. 14:38

알고스팟 : https://www.acmicpc.net/problem/1261

 

토론 : https://www.acmicpc.net/board/view/6593

 

dfs로 완탐하기에는 timeout으로 실패,

bfs하자니 0,1구분을 어떻게 해야할지 애매하고...

 

토론을 보니 다익스트라로 푸는 것이 쉽다는 아이디어 확인.

벽을 가중치 1짜리 그래프라 생각하고 0은 skip 하면서 aoj값이 작은 것 위주로 처리하면 결국 최단 통과로 N,M으로 도달하게 됨.

 

이문제의 진짜 함정은 입력이 M,N으로 주어진다는 것

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

	static int N, M;
	static int[][] graph;
	static boolean[][] visited;
	static int answer = Integer.MAX_VALUE;
	private static boolean DBG = false;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(br.readLine());
		M = Integer.parseInt(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		graph = new int[N + 1][M + 1];
		visited = new boolean[N + 1][M + 1];
		for (int i = 1; i <= N; ++i) {
			char[] ca = br.readLine().toCharArray();
			for (int j = 1; j <= M; ++j) {
				graph[i][j] = ca[j - 1] - '0';
			}
		}

		for (int[] ar : graph) {
			for (int v : ar)
				System.out.print(v + " ");
			System.out.println();
		}

		// dfs(1,1,0);
		bfs();
	}

	private static void bfs() {
		PriorityQueue<Pos> Q = new PriorityQueue<>();
		Q.offer(new Pos(1, 1, 0));
		visited[1][1] = true;

		while (!Q.isEmpty()) {

			int size = Q.size();

			for (int q = 0; q < size; ++q) {
				Pos now = Q.poll();
				if (now.x == N && now.y == M) {
					System.out.println(now.aoj);
					return;
				}

				for (int i = 0; i < 4; ++i) {
					int nx = now.x + dx[i];
					int ny = now.y + dy[i];
					if (nx >= 1 && nx <= N && ny >= 1 && ny <= M && !visited[nx][ny]) {
						if (DBG)
							System.out.printf("[%d %d] %d\n", nx, ny, now.aoj);
						if (graph[nx][ny] == 0)
							Q.offer(new Pos(nx, ny, now.aoj));
						else
							Q.offer(new Pos(nx, ny, now.aoj + 1));
						visited[nx][ny] = true;
					}
				}

			}
		}
	}

	static int[] dx = { 0, 0, 1, -1 };
	static int[] dy = { 1, -1, 0, 0 };

	private static void dfs(int x, int y, int aoj) {
		if (aoj >= answer)
			return;

		if (visited[x][y])
			return;

		visited[x][y] = true;

		if (x == N && y == M) {
			answer = Math.min(answer, aoj);
		} else {
			for (int i = 0; i < 4; ++i) {

				int nx = x + dx[i];
				int ny = y + dy[i];

				if (nx >= 1 && nx <= N && ny >= 1 && ny <= M && !visited[nx][ny]) {
					if (graph[nx][ny] == 1) {
						dfs(nx, ny, aoj + 1);
					} else {
						dfs(nx, ny, aoj);
					}

				}
			}

		}

		visited[x][y] = false;
	}

}

class Pos implements Comparable<Pos> {
	int x, y, aoj;

	Pos(int x, int y, int aoj) {
		this.x = x;
		this.y = y;
		this.aoj = aoj;
	}

	@Override
	public int compareTo(Pos o) {
		return this.aoj - o.aoj;
	}
}

 

'PS > BOJ' 카테고리의 다른 글

부분 수열 DFS 기본형태  (0) 2022.05.05
1208  (0) 2022.05.05
1644  (0) 2022.05.04
1806  (0) 2022.05.04
2003  (0) 2022.05.03
Posted by easy16