Algorithm Test/백준

[백준] 19581. 두 번째 트리의 지름 (JAVA)

김맷돌 2021. 6. 2. 12:00
반응형

📏 두 번째 트리의 지름

 

별 거 아닌데 이상한 개념에 사로잡혀서 헤맸어 . .

 


문제

트리에 N개의 정점이 있고, 각 정점 별로 1부터 N까지의 번호가 붙어있다.

 

트리에서 가장 먼 두 정점 간의 거리를 트리의 지름이라고 한다. 트리의 지름을 구하는 문제는 너무 많기 때문에 우리는 두 번째 트리의 지름을 구하려고 한다.

 

두 번째 트리의 지름은 무엇이냐? 바로 두 번째로 가장 먼 두 정점 간의 거리를 의미한다. (두 번째 트리의 지름은 트리의 지름과 같을 수 있다.)

 

바로 두 번째 트리의 지름을 구해보자.

 

입력

첫 번째 줄에는 정점의 개수 N(3 ≤ N ≤ 100,000)이 들어온다.

 

둘째 줄부터 N번째 줄까지 각 간선에 대한 정보가 들어온다. 간선에 대한 정보는 세 개의 정수로 이루어져 있다. 첫 번째 정수와 두 번째 정수는 간선과 연결된 정점 번호를 나타내고, 세 번째 정수는 간선의 가중치를 나타낸다. 간선의 가중치는 20,000 이하의 자연수이다.

 

출력

첫째 줄에 두 번째 트리의 지름을 출력한다.

 


🔑 IDEA 

트리의 지름을 구하는 방법은 다음과 같다.

  1. 임의의 노드로부터 가장 먼 노드 A를 찾는다. 
  2. 노드 A로부터 가장 먼 노드 B를 찾아 A-B 간의 거리를 구하면 트리의 지름이다.  

그런데 이 문제의 경우 두 번째 트리의 지름을 구해야 한다. 

나는 처음에 이 두 번째 트리의 지름이란 이 A-B에서 Math.max(A를 뺐을 때 거리, B를 뺐을 때 거리) 라고 생각했다..  ㅡ ㅡ

 

근데 그게 아니고, 

Math.max(B를 제외하고 A로부터 가장 먼 노드까지의 거리, A를 제외하고 B로부터 가장 먼 노드까지의 거리)

이렇게 접근해야 한다.

 

그래서, getFarthest() 메서드의 인자에 'except' 라는 인자를 전달하여 

가장 먼 노드를 찾을 때 except 노드를 무시할 수 있도록 해준다. 

 

 

💡  나의 풀이

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

class Node {
	int val;
	int weight;

	Node(int val, int weight) {
		this.val = val;
		this.weight = weight;
	}
}

class Main {
	static int N;
	static List<Node>[] edges;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		edges = new ArrayList[N+1];

		for(int i=1; i<=N; i++) edges[i] = new ArrayList<>();
		for(int i=0; i<N-1; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			if(!st.hasMoreTokens()) break;
			int n1 = Integer.parseInt(st.nextToken());
			int n2 = Integer.parseInt(st.nextToken());
			int w = Integer.parseInt(st.nextToken());
			edges[n1].add(new Node(n2, w));
			edges[n2].add(new Node(n1, w));
		}

		Node endPoint1 = getFarthest(1,0);
		Node endPoint2 = getFarthest(endPoint1.val, 0);
		int dist1 = getFarthest(endPoint1.val, endPoint2.val).weight;
		int dist2 = getFarthest(endPoint2.val, endPoint1.val).weight;

		System.out.println(Math.max(dist1, dist2));

	}

	private static Node getFarthest(int start, int except) {
		Queue<Node> queue = new LinkedList<>();
		boolean[] visited = new boolean[N+1];
		Node farthest = new Node(start, 0);

		queue.offer(farthest);

		while(!queue.isEmpty()) {
			Node cur = queue.poll();
			visited[cur.val] = true;

			if(cur.weight > farthest.weight && cur.val != except)
				farthest = cur;

			for(Node next: edges[cur.val]) {
				if(visited[next.val]) continue;
				visited[next.val] = true;
				queue.offer(new Node(next.val, cur.weight + next.weight));
			}
		}
		return farthest;
	}
}

 

 


 

 

19581번: 두 번째 트리의 지름

트리에 N개의 정점이 있고, 각 정점 별로 1부터 N까지의 번호가 붙어있다. 트리에서 가장 먼 두 정점 간의 거리를 트리의 지름이라고 한다. 트리의 지름을 구하는 문제는 너무 많기 때문에 우리

www.acmicpc.net

 

반응형

'Algorithm Test > 백준' 카테고리의 다른 글

[백준] 10986. 나머지 합 (JAVA)  (1) 2021.05.31
[백준] 7579. 앱 (JAVA)  (0) 2021.05.31
[백준] 12865. 평범한 배낭 (JAVA)  (0) 2021.05.31
[백준] 1005. ACM Craft (JAVA)  (0) 2021.05.20
[백준] 1949. 우수 마을 (JAVA)  (0) 2021.05.20