Difference Between Maximum and Minimum Price Sum
Difference Between Maximum and Minimum Price Sum
There exists an undirected and initially unrooted tree with nodes indexed from to . You are given the integer and a 2D integer array edges of length , where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
Each node has an associated price. You are given an integer array price, where price[i] is the price of the ith node.
The price sum of a given path is the sum of the prices of all nodes lying on that path.
The tree can be rooted at any node root of your choice. The incurred cost after choosing root is the difference between the maximum and minimum price sum amongst all paths starting at root.
Return the maximum possible cost amongst all possible root choices.
Example 1:
Input: n = 6, edges = [[0,1],[1,2],[1,3],[3,4],[3,5]], price = [9,8,7,6,10,5] Output: 24 Explanation: The diagram above denotes the tree after rooting it at node 2. The first part (colored in red) shows the path with the maximum price sum. The second part (colored in blue) shows the path with the minimum price sum. - The first path contains nodes [2,1,3,4]: the prices are [7,8,6,10], and the sum of the prices is 31. - The second path contains the node [2] with the price [7]. The difference between the maximum and minimum price sum is 24. It can be proved that 24 is the maximum cost.
Example 2:
Input: n = 3, edges = [[0,1],[1,2]], price = [1,1,1] Output: 2 Explanation: The diagram above denotes the tree after rooting it at node 0. The first part (colored in red) shows the path with the maximum price sum. The second part (colored in blue) shows the path with the minimum price sum. - The first path contains nodes [0,1,2]: the prices are [1,1,1], and the sum of the prices is 3. - The second path contains node [0] with a price [1]. The difference between the maximum and minimum price sum is 2. It can be proved that 2 is the maximum cost.
Constraints:
- .
解题思路
由于每个节点的权值都是正整数,因此最短路径必然就只有根节点这个节点,朴素做法就是枚举每个点作为根节点然后dfs求最长路径,然后再减去根节点的权值,时间复杂度为。
正解是树形dp,与求树的直径几乎一样,不过后面算答案的时候会有些变化。由于是求树的最长路径,因此这条最长路径的两个端点必然是度数为的端点(这里的个度数指该节点要么只有父节点,要么只有一个子节点。否则还可以继续往其他节点走,路径权值会变大,矛盾),因此这个树的最长路径就是树的直径,而树的直径可以通过树形dp来求解,时间复杂度为。
在求完两边dfs后会得到每个节点的和,其中表示以节点为根的子树的最长路径,表示从节点向其父节点走的最长路径。由于答案是最长路径减去一个端点的值,这个端点必然是度数为的节点,因此在枚举时只计算度数为的节点,如果节点的度数为,那么以为端点要求的路径权值就是。
AC代码如下:
1 class Solution { 2 public: 3 long long maxOutput(int n, vector<vector<int>>& edges, vector<int>& price) { 4 vector<vector<int>> g(n); 5 for (auto &p : edges) { 6 g[p[0]].push_back(p[1]); 7 g[p[1]].push_back(p[0]); 8 } 9 vector<long long> d1(n), d2(n), son(n, -1), up(n); 10 function<void(int, int)> dfs_d = [&](int u, int pre) { 11 d1[u] = price[u]; 12 for (auto &i : g[u]) { 13 if (i != pre) { 14 dfs_d(i, u); 15 int d = d1[i] + price[u]; 16 if (d >= d1[u]) d2[u] = d1[u], d1[u] = d, son[u] = i; 17 else if (d > d2[u]) d2[u] = d; 18 } 19 } 20 }; 21 function<void(int, int)> dfs_up = [&](int u, int pre) { 22 up[u] += price[u]; 23 for (auto &i : g[u]) { 24 if (i != pre) { 25 if (son[u] != i) up[i] += max(up[u], d1[u]); 26 else up[i] += max(up[u], d2[u]); 27 dfs_up(i, u); 28 } 29 } 30 }; 31 dfs_d(0, -1); 32 dfs_up(0, -1); 33 long long ret = 0; 34 for (int i = 0; i < n; i++) { 35 if (g[i].size() == 1) ret = max(ret, max(d1[i], up[i]) - price[i]); 36 } 37 return ret; 38 } 39 };
参考资料
二维差分模板 双指针 树形DP【力扣周赛 328】:https://www.bilibili.com/video/BV1QT41127kJ/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17059540.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效