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:
i
, if amount[i]
is negative, or,i
, otherwise.The game goes on as follows:
0
and Bob is at node bob
.0
.c
, then both Alice and Bob pay c / 2
each. Similarly, if the reward at the gate is c
, both of them receive c / 2
each.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’s net income is now -2.
Since they reach here simultaneously, they open the gate together and share the reward.
Alice’s net income becomes -2 + (4 / 2) = 0.
Bob moves on to node 0, and stops moving.
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 <= 105
edges.length == n - 1
edges[i].length == 2
0 <= ai, bi < n
ai != bi
edges
represents a valid tree.1 <= bob < n
amount.length == n
amount[i]
is an even integer in the range [-104, 104]
.import java.util.Arrays;
public class Solution {
public int mostProfitablePath(int[][] edges, int bob, int[] amount) {
int n = amount.length;
int[][] g = packU(n, edges);
int[][] pars = parents(g, 0);
int[] par = pars[0];
int[] ord = pars[1];
int[] dep = pars[2];
int u = bob;
for (int i = 0; i < (dep[bob] + 1) / 2; i++) {
amount[u] = 0;
u = par[u];
}
if (dep[bob] % 2 == 0) {
amount[u] /= 2;
}
int[] dp = new int[n];
for (int i = n - 1; i >= 0; i--) {
int cur = ord[i];
if (g[cur].length == 1 && i > 0) {
dp[cur] = amount[cur];
} else {
dp[cur] = Integer.MIN_VALUE / 2;
for (int e : g[cur]) {
if (par[cur] == e) {
continue;
}
dp[cur] = Math.max(dp[cur], dp[e] + amount[cur]);
}
}
}
return dp[0];
}
private int[][] parents(int[][] g, int root) {
int n = g.length;
int[] par = new int[n];
Arrays.fill(par, -1);
int[] depth = new int[n];
depth[0] = 0;
int[] q = new int[n];
q[0] = root;
int r = 1;
for (int p = 0; p < r; p++) {
int cur = q[p];
for (int nex : g[cur]) {
if (par[cur] != nex) {
q[r++] = nex;
par[nex] = cur;
depth[nex] = depth[cur] + 1;
}
}
}
return new int[][] {par, q, depth};
}
private int[][] packU(int n, int[][] ft) {
int[][] g = new int[n][];
int[] p = new int[n];
for (int[] u : ft) {
p[u[0]]++;
p[u[1]]++;
}
for (int i = 0; i < n; i++) {
g[i] = new int[p[i]];
}
for (int[] u : ft) {
g[u[0]][--p[u[0]]] = u[1];
g[u[1]][--p[u[1]]] = u[0];
}
return g;
}
}