문제 : 요새 (난이도 : 中)
분석
주어진 데이터를 트리 형태로 가공하면 쉽게 답을 구할 수 있다. 트리 형태에서 최장 길이는 다음 중 긴 길이에 해당된다.
1. 트리의 높이
2. 잎-잎 길이
입력 데이터 중 첫 번째 데이터는 성 외곽이므로 트리의 root로 설정하고, 나머지 tree를 구성하면 된다.
구현
struct TreeNode
{
vector<TreeNode*> children;
};
// leaf to leaf len
int longest;
// root를 루트로하는 subtree의 높이를 반환.
int height(TreeNode* root)
{
vector<int> heights;
for (size_t i = 0; i < root->children.size(); i++)
{
heights.push_back(height(root->children[i]));
}
if (heights.empty()) return 0;
sort(heights.begin(), heights.end());
if (heights.size() >= 2)
{
longest = max(longest, 2 + heights[heights.size() - 2] +
heights[heights.size() - 1]);
}
return heights.back() + 1;
}
// 노드 사이 가장 긴 경로의 길이를 계산
int solve(TreeNode* root)
{
longest = 0;
// 트리의 높이와 최대 잎-잎 경로 중 큰 것을 선택
int h = height(root);
return max(longest, h);
}
// input datas 가공
int n, y[100], x[100], rad[100];
int sqr(int x)
{
return x * x;
}
// 두 성벽 a, b 중심점 간의 거리의 제곱을 반환
int sqrdist(int a, int b)
{
return sqr(y[a] - y[b]) + sqr(x[a] - x[b]);
}
// 성벽 a 가 성벽 b를 포함하는지 반환
bool encloses(int a, int b)
{
return rad[a] > rad[b] && sqrdist(a, b) < sqr(rad[a] - rad[b]);
}
// 성벽 트리에서 parent가 child의 부모인지 확인
bool isChild(int parent, int child)
{
if (!encloses(parent, child)) return false;
for (size_t i = 0; i < n; i++)
{
if (i != parent && i != child &&
encloses(parent, i) && encloses(i, child)) return false;
}
return true;
}
// root 성벽을 루트로 하는 트리를 생성
TreeNode* getTree(int root)
{
TreeNode* ret = new TreeNode();
for (int ch = 0; ch < n; ch++)
{
// ch 성벽이 root 성벽에 직접적으로 포함되어 있다면
// 트리를 만들고 자손 목록에 추가
if (isChild(root, ch))
{
ret->children.push_back(getTree(ch));
}
}
return ret;
}
int main()
{
int c;
cin >> c;
while (c--)
{
cin >> n;
for (size_t i = 0; i < n; i++)
{
cin >> x[i] >> y[i] >> rad[i];
}
TreeNode* root = getTree(0);
cout << solve(root) << '\n';
}
return 0;
}
height() 함수를 해석하는 데 오래 걸렸다...
'알고리즘 > 알고리즘 문제 해결 전략' 카테고리의 다른 글
알고스팟 - 너드인가, 너드가 아닌가? 2 (0) | 2021.01.20 |
---|---|
이진 탐색 트리(Binary Search Tree) (0) | 2021.01.17 |
알고스팟 - 트리 순회 순서 변경 (0) | 2021.01.10 |
알고스팟 - 외계 신호 분석 (0) | 2021.01.09 |
스택 - 1. 짝이 맞지 않은 괄호 (0) | 2021.01.08 |