Closest Node to Path in Tree

For each query, find the node on the path between two endpoints that is closest to a target node.

Hard
Time O((N + Q) * N) Space O(N)
8 min read
tree bfs graph

Problem#

You are given an unrooted tree of N nodes and a list of queries (s, t, target). For each query, return the node lying on the path from s to t whose distance to target is minimum. This is an curriculum variant of LeetCode tree-path queries.

Examples#

  • Path tree 0 - 1 - 2 - 3, query (0, 3, 2)2 (target is already on the path).
  • Star tree with center 0, leaves 1, 2, 3, query (1, 2, 3)0 (only 0 is on both paths).

Constraints#

  • 1 <= N <= 10^4, 1 <= Q <= 10^4.

Hints#

Hint 1
BFS from target first to label dist[v] for every node.
Hint 2
Recover the s -> t path by parent-tracing a second BFS from s, then pick the minimum-dist node on it.

Approach#

For each query: BFS from target to compute distances; BFS from s recording parents to recover the path to t. Walk that path and return the node with smallest distance to target.

Solution#

Closest Node to Path in Tree
class Solution {
public:
int closestNode(int N, vector<vector<int>>& edges, int s, int t, int target) {
vector<vector<int>> g(N);
for (auto& e : edges) { g[e[0]].push_back(e[1]); g[e[1]].push_back(e[0]); }
vector<int> distTarget = bfsDist(g, N, target);
vector<int> parent = bfsParent(g, N, s);
// Reconstruct s -> t path.
vector<int> path;
for (int v = t; v != -1; v = parent[v]) path.push_back(v);
// Find min distance node on path.
int best = path[0], bestD = distTarget[path[0]];
for (int v : path) if (distTarget[v] < bestD) { bestD = distTarget[v]; best = v; }
return best;
}
private:
vector<int> bfsDist(vector<vector<int>>& g, int N, int src) {
vector<int> d(N, -1);
queue<int> q; q.push(src); d[src] = 0;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : g[u]) if (d[v] == -1) { d[v] = d[u] + 1; q.push(v); }
}
return d;
}
vector<int> bfsParent(vector<vector<int>>& g, int N, int src) {
vector<int> p(N, -1);
vector<int> seen(N, 0);
queue<int> q; q.push(src); seen[src] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : g[u]) if (!seen[v]) { seen[v] = 1; p[v] = u; q.push(v); }
}
return p;
}
};

Editorial#

The path between two nodes in a tree is unique, so a single BFS-with-parents from s lets us reconstruct it. Pre-computing distances from target once per query lets the path walk be a linear scan. If queries share target, the distance BFS can be cached for a larger speedup.

Complexity#

  • Time: O((N + Q) * N).
  • Space: O(N).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.