2564. Most Profitable Path In A Tree¶
Difficulty: Medium
LeetCode Problem View on GitHub
2564. Most Profitable Path in a Tree
Medium
There is an undirected tree with n nodes labeled from 0 to n - 1, rooted at node 0. You are given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
At every node i, there is a gate. You are also given an array of even integers amount, where amount[i] represents:
- the price needed to open the gate at node
i, ifamount[i]is negative, or, - the cash reward obtained on opening the gate at node
i, otherwise.
The game goes on as follows:
- Initially, Alice is at node
0and Bob is at nodebob. - At every second, Alice and Bob each move to an adjacent node. Alice moves towards some leaf node, while Bob moves towards node
0. - For every node along their path, Alice and Bob either spend money to open the gate at that node, or accept the reward. Note that:
- If the gate is already open, no price will be required, nor will there be any cash reward.
- If Alice and Bob reach the node simultaneously, they share the price/reward for opening the gate there. In other words, if the price to open the gate is
c, then both Alice and Bob payc / 2each. Similarly, if the reward at the gate isc, both of them receivec / 2each.
- If Alice reaches a leaf node, she stops moving. Similarly, if Bob reaches node
0, he stops moving. Note that these events are independent of each other.
Return the maximum net income Alice can have if she travels towards the optimal leaf node.
Example 1:

Input: edges = [[0,1],[1,2],[1,3],[3,4]], bob = 3, amount = [-2,4,2,-4,6] Output: 6 Explanation: The above diagram represents the given tree. The game goes as follows: - Alice is initially on node 0, Bob on node 3. They open the gates of their respective nodes. Alice's net income is now -2. - Both Alice and Bob move to node 1. Since they reach here simultaneously, they open the gate together and share the reward. Alice's net income becomes -2 + (4 / 2) = 0. - Alice moves on to node 3. Since Bob already opened its gate, Alice's income remains unchanged. Bob moves on to node 0, and stops moving. - Alice moves on to node 4 and opens the gate there. Her net income becomes 0 + 6 = 6. Now, neither Alice nor Bob can make any further moves, and the game ends. It is not possible for Alice to get a higher net income.
Example 2:

Input: edges = [[0,1]], bob = 1, amount = [-7280,2350] Output: -7280 Explanation: Alice follows the path 0->1 whereas Bob follows the path 1->0. Thus, Alice opens the gate at node 0 only. Hence, her net income is -7280.
Constraints:
2 <= n <= 105edges.length == n - 1edges[i].length == 20 <= ai, bi < nai != biedgesrepresents a valid tree.1 <= bob < namount.length == namount[i]is an even integer in the range[-104, 104].
Solution¶
class Solution {
private ArrayList<ArrayList<Integer>> adj;
private int parent[];
private int time[];
private class Pair {
int node, cost, current_time;
public Pair(int node, int cost, int current_time) {
this.node = node;
this.cost = cost;
this.current_time = current_time;
}
@Override
public String toString() {
return "(" + node + " " + cost + " " + current_time + ")";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Pair current = (Pair)(obj);
return current.node == node && current.cost == cost && current.current_time == current_time;
}
@Override
public int hashCode() {
return Objects.hash(node, cost, current_time);
}
}
public int mostProfitablePath(int[][] edges, int bob, int[] amount) {
int maxi = Integer.MIN_VALUE;
adj = new ArrayList<>();
for (int i = 0; i <= (int)(1e5 + 1); i++) adj.add(new ArrayList<>());
for (int current[] : edges) {
int u = current[0];
int v = current[1];
adj.get(u).add(v);
adj.get(v).add(u);
maxi = Math.max(maxi, u);
maxi = Math.max(maxi, v);
}
int n = maxi;
parent= new int[n + 1];
parent[0] = -1;
fill_parent(0, -1, parent);
time = new int[n + 1];
Arrays.fill(time, -1);
fill_time(time, bob);
ArrayList<Integer> leaf = new ArrayList<>();
for (int i = 1; i <= n; i++) {
if (adj.get(i).size() == 1) leaf.add(i);
}
int vis[] = new int[n + 1];
int res[] = new int[n + 1];
Queue<Pair> q = new LinkedList<>();
q.offer(new Pair(0, amount[0], 0));
vis[0] = 1;
res[0] = amount[0];
while (q.size() > 0) {
int current_node = q.peek().node;
int current_cost = q.peek().cost;
int current_time = q.peek().current_time;
q.poll();
for (int v : adj.get(current_node)) {
if (vis[v] == 0) {
vis[v] = 1;
if (current_time + 1 == time[v]) res[v] = res[current_node] + amount[v] / 2;
else if(current_time + 1 < time[v] || time[v] == -1) res[v] = amount[v] + res[current_node];
else res[v] = res[current_node];
q.offer(new Pair(v, res[v] , current_time + 1));
}
}
}
int maxi_ans = Integer.MIN_VALUE;
for (int i = 1; i <= n; i++) {
if (adj.get(i).size() == 1) maxi_ans = Math.max(maxi_ans, res[i]);
}
return maxi_ans;
}
private void fill_time(int time[] , int bob) {
int current_time = 0;
time[bob] = current_time;
int pos = bob;
while (pos != -1) {
time[pos] = current_time++;
pos = parent[pos];
}
}
private void fill_parent(int u , int par, int parent[]) {
for (int v : adj.get(u)) {
if (v != par) {
parent[v] = u;
fill_parent(v, u , parent);
}
}
}
}
Complexity Analysis¶
- Time Complexity:
O(?) - Space Complexity:
O(?)
Approach¶
Detailed explanation of the approach will be added here