https://www.acmicpc.net/problem/2644
촌수계산
문제
우리 나라는 가족 혹은 친척들 사이의 관계를 촌수라는 단위로 표현하는 독특한 문화를 가지고 있다. 이러한 촌수는 다음과 같은 방식으로 계산된다. 기본적으로 부모와 자식 사이를 1촌으로 정의하고 이로부터 사람들 간의 촌수를 계산한다. 예를 들면 나와 아버지, 아버지와 할아버지는 각각 1촌으로 나와 할아버지는 2촌이 되고, 아버지 형제들과 할아버지는 1촌, 나와 아버지 형제들과는 3촌이 된다.
여러 사람들에 대한 부모 자식들 간의 관계가 주어졌을 때, 주어진 두 사람의 촌수를 계산하는 프로그램을 작성하시오.
입력
사람들은 1, 2, 3, …, n (1 ≤ n ≤ 100)의 연속된 번호로 각각 표시된다. 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고, 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두 사람의 번호가 주어진다. 그리고 셋째 줄에는 부모 자식들 간의 관계의 개수 m이 주어진다. 넷째 줄부터는 부모 자식간의 관계를 나타내는 두 번호 x,y가 각 줄에 나온다. 이때 앞에 나오는 번호 x는 뒤에 나오는 정수 y의 부모 번호를 나타낸다.
각 사람의 부모는 최대 한 명만 주어진다.
출력
입력에서 요구한 두 사람의 촌수를 나타내는 정수를 출력한다. 어떤 경우에는 두 사람의 친척 관계가 전혀 없어 촌수를 계산할 수 없을 때가 있다. 이때에는 -1을 출력해야 한다.
예제 입력 1 복사
9
7 3
7
1 2
1 3
2 7
2 8
2 9
4 5
4 6
예제 출력 1 복사
3
풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static int N;
static boolean[] visited;
static ArrayList<Integer>[] A;
static int start, end;
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine()); // 사람 수
A = new ArrayList[N+1]; // 사람번호 1부터 시작
visited = new boolean[N+1]; // 방문배열 초기화
StringTokenizer st = new StringTokenizer(br.readLine());
// 촌수 계산할 대상 2명
start = Integer.parseInt(st.nextToken());
end = Integer.parseInt(st.nextToken());
// 인접리스트 만들어주기
for(int i=1; i<N+1; i++){
A[i] = new ArrayList<>();
}
int m = Integer.parseInt(br.readLine()); // 관계 개수
for(int i=0; i<m; i++){
st = new StringTokenizer(br.readLine());
int parent = Integer.parseInt(st.nextToken());
int child = Integer.parseInt(st.nextToken());
// 양방향 그래프 연결
A[parent].add(child);
A[child].add(parent);
}
int result = DFS(start,0);
System.out.println(result);
}
private static int DFS(int node, int depth){
// 이번 노드가 end라면 종료
if (node == end) return depth;
// 방문한 노드가 아니라면 방문체크 후, count증가
visited[node] = true;
// 인접노드 리스트 순회
for(int now : A[node]){
if (!visited[now]){
int result = DFS(now, depth+1);
if (result != -1) return result; // 목표 노드 찾으면 즉시 반환
}
}
return -1; // 경로가 없을 경우
}
}
- 그래프탐색을 활용한 문제, 나는 DFS로 풀이하였다.
- 촌수 계산할 대상 start, end를 받아준다.
- 부모-자식 관계를 인접리스트로 양방향 연결해준다.
- start노드부터 DFS 탐색을 수행해준다.
- DFS
- 파라미터로 탐색시작할 node, 현재 depth를 받아준다. 처음의 depth는 0으로 시작한다.
- 종료조건 : 현재들어온 node가 end(목표노드)라면 depth 반환 후 return
- 방문한 노드가 아니라면 visited[node]에 방문체크후 인접노드 리스트를 순회한다.
- node의 인접리스트를 순회한다.
- 현재 노드(now)가 방문한적 없는 노드라면 depth증가 후 DFS 재귀호출한다.
- 만약 재귀호출한 DFS return 값이 -1이 아니라면 result 출력 후 함수 종료한다.
- 경로가 없을경우에는 -1을 반환한다.
'코딩테스트 > 백준' 카테고리의 다른 글
[백준 7795] 먹을 것인가 먹힐 것인가 (Java) - 투포인터 (0) | 2025.04.05 |
---|---|
[백준 1238] 파티 (Java) - 다익스트라 (0) | 2025.04.04 |
[백준 2468] 안전 영역 (Java) - BFS풀이 (0) | 2025.04.03 |
[백준 10844] 쉬운 계단 수 (Java) - 다이나믹 프로그래밍 (0) | 2025.04.02 |
[백준 11726] 2×n 타일링 (Java) - 다이나믹프로그래밍 (0) | 2025.04.02 |