Diameter of a tree
The Diameter of tree is the maximum length between two nodes. For example :
Consider the following tree of 7 nodes
Here, Diameter = 4 .
Algorithm
First, root the tree arbitarily.
For each node, we calculate toLeaf(node) which denotes
maximum length of a path from the node to any leaf.
if node is leaf :
toLeaf[node] = 0
else
toLeaf[node] = 1 + max(toLeaf[child]) | for all child of node
We can use DFS to calculate toLeaf(node).
vector<int> toLeaf(n+1, 0); // n is no. of nodes
void dfs(int node){
visited[node] = true;
for(int child : tree[node]){
if(visited[child])
continue;
dfs(child);
toLeaf[node] = max(toLeaf[node], 1 + toLeaf[child]);
}
}
Now calculate path_length(node) which denotes maximum length of a path whose highest point is node.
if node is leaf :
path_length[node] = 0
else if node has only 1 child :
path_length[node] = toLeaf[child] + 1
else
Take two distinct child a,b such that (toLeaf[a] + toLeaf[b]) is maximum, then
path_length[node] = (toLeaf[a] + 1) + (toLeaf[b] + 1)
Here is the implementation .
vector<int> toLeaf(n+1, 0), path_length(n+1, 0);
void dfs(int node){
visited[node] = true;
vector<int> length = {-1}; // allows us to handle the cases when node has less than 2 children
for(int child : tree[node]){
if(visited[child])
continue;
dfs(child);
toLeaf[node] = max(toLeaf[node], 1 + toLeaf[child]);
length.push_back(toLeaf[child]);
}
int s = length.size(), m = min((int)length.size(),2);
for(int i = 0; i < m; i++){
for(int j = i+1; j < s; j++){
if(length[i] < length[j])
swap(length[i], length[j]);
}
path_length[node] += length[i] + 1;
}
}
Finally, Diameter = maximum of all lengths in path_length. Therefore here, Diameter = 4.
Problems
Reference
- Competitive Programmer's Handbook by Antii Laaksonen.