트리에서 가장 멀리 떨어진 정점 사이의 거리는
임의의 점 x,
x에서 가장 먼 거리에 있는 정점 y,
y와 가장 먼 거리에 있는 정점 z라 할 때
y와 z사이의 거리와 같다.
트리 내에서 거리가 가장 먼 두 정점을 u와 v,
임의의 정점 x에서 가장 멀리 떨어진 점을 y라 할 때
가능한 경우는 아래와 같다.
#include <bits/stdc++.h>
using namespace std;
int N, maxEat = INT_MIN;
vector<int> tree;
vector<int> starts;
vector<int> results;
vector<vector<int>> edge;
void input(){
cin >> N;
tree.push_back(-1);
for(int i=1; i<=N; i++){
int fruit;
cin >> fruit;
tree.push_back(fruit);
}
edge.resize(N+1);
for(int i=0; i<N-1; i++){
int to, from;
cin >> to >> from;
edge.at(to).push_back(from);
edge.at(from).push_back(to);
}
}
void buildStarts(int now, int prev, int eat){
eat += tree.at(now);
if(maxEat <= eat){
if(maxEat < eat) starts.clear();
maxEat = eat;
starts.push_back(now);
}
vector<int> adj = edge.at(now);
for(int i=0; i < adj.size(); i++){
int next = adj.at(i);
if(next != prev){
buildStarts(next, now, eat);
}
}
return ;
}
// 트리의 지름 위에 있는 vertex(starts)를 찾음
void buildEnds(int startVtx, int now, int prev, int eat){
eat += tree.at(now);
if(maxEat <= eat){
if(maxEat < eat) results.clear();
maxEat = eat;
results.push_back(min(startVtx, now));
}
vector<int> adj = edge.at(now);
for(int i=0; i < adj.size(); i++){
int next = adj.at(i);
if(next != prev){
buildEnds(startVtx, next, now, eat);
}
}
return;
}
// vertex(starts)에서 시작해 가장 먼 정점(results)을 구함
void outputStarts(){
for(int i=0; i<starts.size(); i++){
cout << starts.at(i) << " ";
}
cout << endl;
}
void output(){
cout << maxEat << " " << results.at(0) <<endl;
}
void forEnds(){
for(auto& startVtx : starts){
buildEnds(startVtx, startVtx, 0, 0);
}
sort(results.begin(), results.end());
}
void run(){
input();
buildStarts(1, 0, 0);
forEnds();
output();
}
int main(){
run();
return 0;
}
https://johoonday.tistory.com/217
https://velog.io/@besyia0k0/Algorithm-diameter-of-tree