Tree Algorithms: Diameter & Longest Paths¶
A tree is a connected undirected graph with no cycles. Many problems use two DFS/BFS passes or tree DP.
Tree diameter¶
The diameter is the maximum distance between any two nodes (in edges or in sum of weights).
Unweighted / unit edges: run BFS/DFS from any node a, find farthest b; run again from b, distance to farthest is the diameter.
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
// Returns (farthest_node, distance) from start in unweighted tree
pair<int, int> bfsFarthest(int start, const vector<vector<int>>& adj) {
int n = (int)adj.size();
vector<int> dist(n, -1);
queue<int> q;
dist[start] = 0;
q.push(start);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : adj[u])
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
int far = start;
for (int i = 0; i < n; i++)
if (dist[i] > dist[far]) far = i;
return {far, dist[far]};
}
int treeDiameterEdges(const vector<vector<int>>& adj) {
int a = bfsFarthest(0, adj).first;
return bfsFarthest(a, adj).second;
}
For weighted trees, use DFS with accumulated distance or a priority-based longest path from each side of the two-pass method.
Longest path in a tree¶
The longest simple path is exactly the diameter (trees have a unique simple path between any two nodes).
Binary trees¶
A rooted binary tree is a special case: DP often has states (node) or (node, parent). Same diameter trick works on the underlying undirected tree.
Related¶
- DFS / BFS — traversal
- LCA & Tree Queries — paths and ancestors
- DP on Trees / Graphs — subtree DP