[백준/자바] 1167 트리의 지름
📌 문제
트리의 지름이란, 트리에서 임의의 두 점 사이의 거리 중 가장 긴 것을 말한다. 트리의 지름을 구하는 프로그램을 작성하시오.
⚔ 입력
트리가 입력으로 주어진다. 먼저 첫 번째 줄에서는 트리의 정점의 개수 V가 주어지고 (2 ≤ V ≤ 100,000)둘째 줄부터 V개의 줄에 걸쳐 간선의 정보가 다음과 같이 주어진다. 정점 번호는 1부터 V까지 매겨져 있다.
먼저 정점 번호가 주어지고, 이어서 연결된 간선의 정보를 의미하는 정수가 두 개씩 주어지는데, 하나는 정점번호, 다른 하나는 그 정점까지의 거리이다. 예를 들어 네 번째 줄의 경우 정점 3은 정점 1과 거리가 2인 간선으로 연결되어 있고, 정점 4와는 거리가 3인 간선으로 연결되어 있는 것을 보여준다. 각 줄의 마지막에는 -1이 입력으로 주어진다. 주어지는 거리는 모두 10,000 이하의 자연수이다.
📣 출력
첫째 줄에 트리의 지름을 출력한다.
💎 문제분석하기
문제 해결의 아이디어는 임의의 수에서 거리를 계산했을 때 가장 먼 거리에 있는 노드는 반드시 최대 경로로 설정되는 두 개의 노드 중 하나일 것이라는 것이다.
이 개념을 바탕으로 먼저 1개의 노드를 구하고 그 숫자에서부터 다시 최대 거리에 있는 노드를 구하면 해당 두 노드의 거리가 최대 거리가 된다.
거리를 측정하기 위해 임시의 배열을 설정하며 이 배열은 최종 답안까지 사용되기 때문에 초기화 해준다.
예제를 토대로 손으로 풀어보면
임의의 노드 2로부터 시작한다고 했을 때
2 -> 4 -> 3 -> 1 -> 5
가는 동안 가장 거리가 먼 5에 10의 숫자가 구해진다
그렇다면 이제 5부터 다시 시작을 해서 가장 큰 값이 나오는 노드를 찾고, 그때의 값이 최대값이 되는 것이다.
💡 코드 구현하기
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static boolean[] visited;
static int[] distance;
static ArrayList<edge>[] adjacentNodes;
public static void main(String[] args) {
/**
* 문제 해결의 아이디어는
* 임의의 수에서 거리를 계산했을 때 가장 먼 거리에 있는 노드는
* 반드시 최대 경로로 설정되는 두 개의 노드 중 하나일 것이라는 것이다
* <p>
* 이 개념을 바탕으로 먼저 1개의 노드를 구하고
* 그 숫자에서부터 다시 최대 거리에 있는 노드를 구하면
* 해당 두 노드의 거리가 최대 거리가 된다
* <p>
* 거리를 측정하기 위해 임시의 배열을 설정한다
*/
Scanner scanner = new Scanner(System.in);
int numberOfNodes = scanner.nextInt(); // 입력 받는 노드의 개수
setUptAdjacentNodesStorage(numberOfNodes);
saveNodeMap(scanner, numberOfNodes);
bfs(1); // 임의의 점 (1로 세팅)에서 bfs 탐색
bfs(findMaxDistanceNode(numberOfNodes)); // 가장 큰 값을 지니는 노드를 찾고 해당 노드를 시작점으로 지정
System.out.println(Arrays.stream(distance).max().getAsInt()); // 최대값을 출력
}
private static int findMaxDistanceNode(int numberOfNodes) {
int Max = 1;
for (int i = 2; i <= numberOfNodes; i++) {
if (distance[Max] < distance[i])
Max = i;
}
initializeCalculationModules(numberOfNodes);
return Max;
}
private static void initializeCalculationModules(int numberOfNodes) {
distance = new int[numberOfNodes + 1];
visited = new boolean[numberOfNodes + 1];
}
private static void saveNodeMap(Scanner sc, int numberOfNodes) {
for (int i = 0; i < numberOfNodes; i++) {
int thisNode = sc.nextInt();
while (true) {
int otherNode = sc.nextInt();
if (otherNode == -1) break;
int cost = sc.nextInt();
adjacentNodes[thisNode].add(new edge(otherNode, cost));
}
}
initializeCalculationModules(numberOfNodes);
}
private static void setUptAdjacentNodesStorage(int N) {
adjacentNodes = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) {
adjacentNodes[i] = new ArrayList<>();
}
}
private static void bfs(int node) {
Queue<Integer> queue = new LinkedList<>();
queue.add(node);
visited[node] = true;
while (!queue.isEmpty()) {
int now_node = queue.poll();
for (edge edge : adjacentNodes[now_node]) {
int otherNode = edge.edge;
int cost = edge.value;
if (!visited[otherNode]) {
visited[otherNode] = true;
queue.add(otherNode);
Main.distance[otherNode] = Main.distance[now_node] + cost; // 거리 배열 업데이트 로직
}
}
}
}
}
class edge {
int edge;
int value;
public edge(int edge, int cost) {
this.edge = edge;
this.value = cost;
}
}
풀이 참고 : Do it! 알고리즘 코딩테스트 - 자바 편
반응형
'알고리즘 > 백준' 카테고리의 다른 글
[백준/자바] 1717 집합 표현하기 (0) | 2022.11.25 |
---|---|
[백준/자바] K번째 수 (0) | 2022.11.24 |
[백준/자바] 13023 ABCDE 친구 관계 파악하기 (0) | 2022.11.23 |
[백준/파이썬] 1517 버블 소트 (0) | 2022.11.08 |
[백준/자바] 2751 수 정렬하기 2 (0) | 2022.11.08 |