백준
[백준 JAVA] 2644 : 촌수계산
mak-ing
2024. 3. 10. 21:47
[백준 2644] 촌수계산 : https://www.acmicpc.net/problem/2644
2644번: 촌수계산
사람들은 1, 2, 3, …, n (1 ≤ n ≤ 100)의 연속된 번호로 각각 표시된다. 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고, 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두 사람의 번호가 주어
www.acmicpc.net
문제 조건 정리
- 기본적으로 부모와 자식 사이를 1촌으로 정의하고 이로부터 사람들 간의 촌수를 계산한다.
- [나, 아버지] -> 1촌, [아버지, 할아버지]-> 1촌
[나, 할아버지] -> 2촌 [아버지 형제, 할아버지] -> 1촌
[나, 아버지 형제] -> 3촌 - 여러 사람들에 대한 부모 자식들 간의 관계가 주어졌을 때, 주어진 두 사람의 촌수를 계산하는 프로그램을 작성하시오.
입력
- 사람들은 1, 2, 3, …, n (1 ≤ n ≤ 100)의 연속된 번호로 각각 표시된다.
- 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고, 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두 사람의 번호가 주어진다.
- 그리고 셋째 줄에는 부모 자식들 간의 관계의 개수 m이 주어진다.
- 넷째 줄부터는 부모 자식간의 관계를 나타내는 두 번호 x,y가 각 줄에 나온다.
이때 앞에 나오는 번호 x는 뒤에 나오는 정수 y의 부모 번호를 나타낸다. - 각 사람의 부모는 최대 한 명만 주어진다.
문제를 풀기 전
- 부모 자식들 간의 관계는 양방향으로 설정해야겠다고 생각함!
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine());
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i <= n; i++) {
// 1 ~ n 번의 사람들과 1촌인 사람을 정리하기 위한 리스트 초기화
// 0 번도 초기화 해야함
adjList.add(new ArrayList<>());
}
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");
// start부터 end까지 몇 촌인가? 를 구하는 문제
int start = Integer.parseInt(stringTokenizer.nextToken());
int end = Integer.parseInt(stringTokenizer.nextToken());
// 부모 자식들 간의 관계의 개수 m
int m = Integer.parseInt(bufferedReader.readLine());
for (int i = 0; i < m; i++) {
stringTokenizer = new StringTokenizer(bufferedReader.readLine(), " ");
// [first, second] -> 1촌
int first = Integer.parseInt(stringTokenizer.nextToken());
int second = Integer.parseInt(stringTokenizer.nextToken());
// [first, second] -> 1촌
// [second, first] -> 1촌
adjList.get(first).add(second);
adjList.get(second).add(first);
}
// bfs를 위한 큐
// 재방문을 검사하는 visited 배열
// 각 노드까지의 거리를 저장할 distance 배열
Queue<Integer> queue = new ArrayDeque<>();
boolean[] visited = new boolean[n + 1];
int[] distance = new int[n + 1];
// [start, end]를 구하기 위해서 start를 넣고 시작
queue.offer(start);
visited[start] = true;
while (!queue.isEmpty()) {
int current = queue.poll();
// 현재 요소가 도착 지점일 경우 거리 출력하고 끝냄
if (current == end) {
System.out.println(distance[end]);
return;
}
// 현재 요소와 인접한 요소들을 가져옴
List<Integer> adj = adjList.get(current);
// 가져온 요소들을 처리
for (Integer a : adj) {
// 방문한 적이 없다면
if (!visited[a]) {
// 방문 표시
visited[a] = true;
// 큐에 추가
queue.offer(a);
// 큐에 추가된 요소는 (현재 촌수 + 1)로 저장
distance[a] = distance[current] + 1;
}
}
}
// 큐가 비었음에도 end에 도달하지 못했다면 조건대로 -1 출력
System.out.println(-1);
}
}
문제를 풀고 난 후
원래 bfs문제를 해결 할 때, 현재 요소의 깊이를 알아내기 위해서 depth를 포함하는 class를 선언하고 이를 큐에서 사용했었음!
이번에는 distance 배열로 해결해보니 이것도 괜찮다고 생각했음!