|
| 1 | +/** |
| 2 | + * 2467. Most Profitable Path in a Tree |
| 3 | + * https://leetcode.com/problems/most-profitable-path-in-a-tree/ |
| 4 | + * Difficulty: Medium |
| 5 | + * |
| 6 | + * There is an undirected tree with n nodes labeled from 0 to n - 1, rooted at node 0. You are |
| 7 | + * given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that |
| 8 | + * there is an edge between nodes ai and bi in the tree. |
| 9 | + * |
| 10 | + * At every node i, there is a gate. You are also given an array of even integers amount, where |
| 11 | + * amount[i] represents: |
| 12 | + * - the price needed to open the gate at node i, if amount[i] is negative, or, |
| 13 | + * - the cash reward obtained on opening the gate at node i, otherwise. |
| 14 | + * |
| 15 | + * The game goes on as follows: |
| 16 | + * - Initially, Alice is at node 0 and Bob is at node bob. |
| 17 | + * - At every second, Alice and Bob each move to an adjacent node. Alice moves towards some leaf |
| 18 | + * node, while Bob moves towards node 0. |
| 19 | + * - For every node along their path, Alice and Bob either spend money to open the gate at that |
| 20 | + * node, or accept the reward. Note that: |
| 21 | + * - If the gate is already open, no price will be required, nor will there be any cash reward. |
| 22 | + * - If Alice and Bob reach the node simultaneously, they share the price/reward for opening |
| 23 | + * the gate there. In other words, if the price to open the gate is c, then both Alice and |
| 24 | + * Bob pay c / 2 each. Similarly, if the reward at the gate is c, both of them receive |
| 25 | + * c / 2 each. |
| 26 | + * - If Alice reaches a leaf node, she stops moving. Similarly, if Bob reaches node 0, he stops |
| 27 | + * moving. Note that these events are independent of each other. |
| 28 | + * |
| 29 | + * Return the maximum net income Alice can have if she travels towards the optimal leaf node. |
| 30 | + */ |
| 31 | + |
| 32 | +/** |
| 33 | + * @param {number[][]} edges |
| 34 | + * @param {number} bob |
| 35 | + * @param {number[]} amount |
| 36 | + * @return {number} |
| 37 | + */ |
| 38 | +var mostProfitablePath = function(edges, bob, amount) { |
| 39 | + const graph = new Array(edges.length + 1).fill().map(() => []); |
| 40 | + const path = new Array(edges.length + 1).fill(-1); |
| 41 | + |
| 42 | + for (const [u, v] of edges) { |
| 43 | + graph[u].push(v); |
| 44 | + graph[v].push(u); |
| 45 | + } |
| 46 | + |
| 47 | + function traceInitialPath(node, time) { |
| 48 | + path[node] = time; |
| 49 | + if (node === 0) { |
| 50 | + return true; |
| 51 | + } |
| 52 | + for (const next of graph[node]) { |
| 53 | + if (path[next] === -1 && traceInitialPath(next, time + 1)) { |
| 54 | + return true; |
| 55 | + } |
| 56 | + } |
| 57 | + path[node] = -1; |
| 58 | + return false; |
| 59 | + } |
| 60 | + |
| 61 | + traceInitialPath(bob, 0); |
| 62 | + |
| 63 | + function dfs(node, parent, time, income) { |
| 64 | + const current = (time < path[node] || path[node] === -1) |
| 65 | + ? amount[node] |
| 66 | + : time === path[node] ? amount[node] / 2 : 0; |
| 67 | + let maxIncome = graph[node].length === 1 && node !== 0 ? income + current : -Infinity; |
| 68 | + |
| 69 | + for (const next of graph[node]) { |
| 70 | + if (next !== parent) { |
| 71 | + maxIncome = Math.max(maxIncome, dfs(next, node, time + 1, income + current)); |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + return maxIncome === -Infinity ? income + current : maxIncome; |
| 76 | + } |
| 77 | + |
| 78 | + return dfs(0, -1, 0, 0); |
| 79 | +}; |
0 commit comments