Difference Between Maximum and Minimum Price Sum

Difference Between Maximum and Minimum Price Sum

There exists an undirected and initially unrooted tree with n nodes indexed from 0 to n1. You are given the integer n and a 2D integer array edges of length n1, 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:

  • 1n105
  • edges.length == n1
  • 0ai,bin1
  • edges represents a valid tree.
  • price.length == n
  • 1price[i]105

 

解题思路

  由于每个节点的权值都是正整数,因此最短路径必然就只有根节点这个节点,朴素做法就是枚举每个点作为根节点然后dfs求最长路径,然后再减去根节点的权值,时间复杂度为O(n2)

  正解是树形dp,与求树的直径几乎一样,不过后面算答案的时候会有些变化。由于是求树的最长路径,因此这条最长路径的两个端点必然是度数为1的端点(这里的1个度数指该节点要么只有父节点,要么只有一个子节点。否则还可以继续往其他节点走,路径权值会变大,矛盾),因此这个树的最长路径就是树的直径,而树的直径可以通过树形dp来求解,时间复杂度为O(n)

  在求完两边dfs后会得到每个节点的d1[i]up[i],其中d1[i]表示以节点i为根的子树的最长路径,up[i]表示从节点i向其父节点走的最长路径。由于答案是最长路径减去一个端点的值,这个端点必然是度数为1的节点,因此在枚举时只计算度数为1的节点,如果节点i的度数为1,那么以i为端点要求的路径权值就是max(d1[i],up[i])w[i]

  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/

posted @   onlyblues  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示