[백준] 1967 1167 트리의 지름
두 문제는 입력부분만 다르고 사실상 같은문제입니다~!
기본적인 접근법은 이렇습니다.
- 트리의 지름 양 끝의 노드를 e1, e2라 할 때, 임의의 노트 x에서 가장 먼거리에 놓여진 노드는 반드시 e1 혹은 e2가 된다.
- e1에서 가장 먼 노드는 e2이고, 그 역도 성립한다.
따라서 아무 노드나 하나 잡고, 가장 먼 노드를 구한 뒤(이게 e1 혹은 e2 둘중에 하나는 알아낼 수 있습니다.)
그 노드에서 가장 먼 노드를 한번 더 구해주면 됩니다! 그럼 그 거리가 반드시 e1과 e2사이의 거리가 되므로 트리의 지름을 구할 수 있습니다.
해당 코드는 1167을 기준으로 작성되었습니다~!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Node{
int num;
int dist;
Node(int num, int dist){
this.num = num;
this.dist = dist;
}
}
class Main{
static int n;
static int max;
static ArrayList<Node>[] list;
// i번째 노드에서 가장 먼 곳의 노드의 번호와 거기까지의 거리를 함께 반환하는 함수
static Node bfs(int i) {
Queue<Node> q = new LinkedList<Node>();
q.add(new Node(i, 0)); // 스타트~!
boolean[] check = new boolean[n+1]; // 방문여부 체크용
check[i] = true;
int maxLen = 0; // 최장거리를 저장
int endNode = -1; // 최장거리일때의 노드를 저장
while(!q.isEmpty()) {
Node n = q.remove();
int num = n.num;
int sumDist = n.dist;
if(maxLen < sumDist) { // 최장거리 갱신
maxLen = sumDist;
endNode = num;
}
// 인접 노드를 쭉 돌며 방문 가능하다면 방문해줍니다
for(Node node:list[num]) {
int next = node.num;
int dist = node.dist;
if(check[next] == false) {
check[next] = true;
q.add(new Node(next, sumDist + dist));
}
}
}
// 반환
return new Node(endNode, maxLen);
}
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
list = (ArrayList<Node>[]) new ArrayList[n+1];
for(int i = 1 ; i <= n ; i++) {
list[i] = new ArrayList<>();
}
for(int i = 0 ; i < n ; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
while(v != -1) {
list[u].add(new Node(v, Integer.parseInt(st.nextToken())));
v = Integer.parseInt(st.nextToken());
}
}
// 임의의 노드로부터 e1혹은 e2를 받아냅니다
Node first = bfs(1);
// 실제로 지름을 구하는 부분
Node second = bfs(first.num);
System.out.println(second.dist);
}
}
Comments