1976번: 여행가자
LV: 골드 4
주어진 도시 개와 도시 간의 연결 정보( 인접 행렬)를 바탕으로, 정해진 여행 계획(개의 도시 순서)을 따라 여행하는 것이 가능한지 판별하는 문제
1: 두 도시가 직접 연결됨 (양방향)0: 연결되지 않음이 문제는 여행 계획에 포함된 모든 인접한 두 도시 쌍에 대해 "출발지에서 도착지로 이동이 가능한가?"를 확인하는 문제이다.
도시 간 이동은 직통 연결이 아니더라도, 경로만 있다면 가능하므로, 이는 그래프 탐색 알고리즘인 BFS 를 이용하여 풀이할 수 있다.
전체 여행 가능 여부를 저장할 tripPossible 변수를 true로 초기화하고, 개의 경로에 대해 반복한다.
boolean tripPossible = true;
// M-1개의 경로 쌍에 대해 반복
for (int sp = 0; sp < M - 1; sp++) {
boolean isPossible = false;
int start = plan[sp]; // 현재 경로의 출발지
int dest = plan[sp + 1]; // 현재 경로의 도착지
boolean[] visited = new boolean[N]; // BFS용 방문 배열 (N: 도시의 수)
// ... (BFS 수행)
// ...
Queue를 사용하여 BFS를 수행
Queue<Integer> q = new LinkedList<>();
q.offer(start);
visited[start] = true;
while (!q.isEmpty()) {
int curr = q.poll();
// **도착지 도달 확인**
if (curr == dest) {
isPossible = true;
break; // 현재 경로 쌍은 가능하므로 BFS 종료
}
// 인접한 모든 도시 탐색 (N: 도시의 수)
for (int next = 0; next < N; next++) {
// 연결되어 있고, 방문하지 않은 도시라면 큐에 추가
if (board[curr][next] == 1 && !visited[next]) {
q.offer(next);
visited[next] = true;
}
}
}
// ...
하나의 경로라도 불가능하면 전체 여행이 불가능하므로, 즉시 반복문을 종료한다.
if (!isPossible) {
tripPossible = false;
break; // 전체 여행 불가능 확정이므로 즉시 반복 종료
}
}
System.out.println(tripPossible ? "YES" : "NO");
코드를 작성할 때 실수했던 두 가지 사항이 있다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class backjoon_1976_여행가자 {
public static void main(String[] args) throws IOException {
// System.setIn(new FileInputStream("src/input.txt")); // 파일 입출력 시 주석 해제
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine()); // 도시의 수
int M = Integer.parseInt(br.readLine()); // 여행 계획에 속한 도시의 수
int[][] board = new int[N][N];
StringTokenizer st;
// 인접 행렬 입력 받기
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
int[] plan = new int[M];
// 여행 계획 입력 받기 (도시 번호 1-based -> 0-based 인덱스로 변경)
st = new StringTokenizer(br.readLine());
for (int i = 0; i < M; i++) {
plan[i] = Integer.parseInt(st.nextToken()) - 1;
}
boolean tripPossible = true;
// M-1개의 순차적인 경로 쌍에 대해 BFS 수행
for (int sp = 0; sp < M - 1; sp++) {
boolean isPossible = false;
int start = plan[sp];
int dest = plan[sp + 1];
boolean[] visited = new boolean[N]; // 경로 쌍마다 방문 배열 초기화
Queue<Integer> q = new LinkedList<>();
q.offer(start);
visited[start] = true;
// BFS 시작
while (!q.isEmpty()) {
int curr = q.poll();
// 목적지에 도달하면 현재 경로 쌍은 가능
if (curr == dest) {
isPossible = true;
break;
}
// 인접한 모든 도시(N개)에 대해 탐색
for (int next = 0; next < N; next++) {
// 직접 연결되어 있고, 아직 방문하지 않은 도시인 경우
if (board[curr][next] == 1 && !visited[next]) {
q.offer(next);
visited[next] = true;
}
}
}
// 현재 경로 쌍이 불가능하면 전체 여행도 불가능
if (!isPossible) {
tripPossible = false;
break;
}
}
System.out.println(tripPossible ? "YES" : "NO");
}
}