Skip to content

Instantly share code, notes, and snippets.

@NamPE286
Created April 11, 2023 18:15
Show Gist options
  • Save NamPE286/f93a5d5acbb32238155afdc7f856f702 to your computer and use it in GitHub Desktop.
Save NamPE286/f93a5d5acbb32238155afdc7f856f702 to your computer and use it in GitHub Desktop.
C++ function to find tree diameter
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <typename T>
class general_tree {
private:
T root;
bool modified = false;
unordered_map<T, vector<T>> graph;
unordered_map<T, T> parent;
unordered_map<T, ll> subtree_size, depth;
void pre_calc_size(ll cur_node) {
subtree_size[cur_node] = 1;
for (T i : graph[cur_node]) {
if (i == parent[cur_node]) continue;
depth[cur_node]++;
pre_calc_size(i);
subtree_size[cur_node] += subtree_size[i];
}
}
void farthest_node(T &ans_node, ll &max_distance, T cur_node, T prev_node = -1, ll distance = 0) {
for (T i : graph[cur_node]) {
if (i == prev_node) continue;
farthest_node(ans_node, max_distance, i, cur_node, distance + 1);
}
if (distance > max_distance) {
max_distance = distance;
ans_node = cur_node;
}
}
public:
general_tree(T tree_root) {
root = tree_root;
}
void connect(T parent_node, T children_node) {
parent[children_node] = parent_node;
graph[parent_node].push_back(children_node);
graph[children_node].push_back(parent_node);
modified = true;
}
ll size(T node) {
if (modified) {
pre_calc_size(root);
modified = false;
}
return subtree_size[node];
}
ll diameter() {
T a;
ll x = -1;
farthest_node(a, x, root);
x = -1;
T b;
farthest_node(b, x, a);
return x;
}
};
int main() {
ll n;
cin >> n;
general_tree<ll> tree(1);
for (ll i = 2; i <= n; i++) {
ll x;
cin >> x;
tree.connect(x, i);
}
cout << tree.diameter();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment