满二叉树等长路径
满二叉树等长路径
给定一个深度为 的满二叉树,其 个顶点的编号为 。
树的根节点为 号节点,除根节点外,第 号节点的父节点为第 号节点。
例如,当 时,二叉树如下所示:
树中每条边的长度已知,由此可以得到根节点到 个叶节点的距离。
为了使得根节点到每个叶节点的距离都相等,我们可以进行任意次增边操作。
每次操作可以选择任意一条边,将其增加任意正整数长度。
我们希望在达成目的的同时,所有边的总增加长度尽可能小。
请你计算并输出总增加长度的最小可能值。
输入格式
第一行包含整数 。
第二行包含 个整数 ,其中 表示第 号节点与第 号节点之间的边的长度。
输出格式
一个整数,表示总增加长度的最小可能值。
数据范围
前三个测试点满足 。
所有测试点满足 。
输入样例:
2 1 2 3 4 5 6
输出样例:
5
解题思路
这题在做的时候猜对了做法,贪心题,难得。
假设根节点到叶子结点的距离都相同,对于上面的左子树,每一个叶子结点到左儿子的距离是相同的。如果不相同,意味着存在两个叶子结点到左儿子的距离不同,即这两个叶子结点到根节点的距离不相等,就与根节点到叶子结点的距离都相同矛盾了。右子树同理。
现在假设左子树的每个叶子结点到根节点的距离为,右子树的每个叶子结点到根节点的距离为。现在我们希望根节点到左右子树的叶子结点的距离都相同,假设最终的距离为,由于只能够增加距离,因此有。那么左子树的每一个叶子结点到根节点的距离就要增加,右子树的每一个叶子结点到根节点的距离就要增加。
对于左子树,我们看一下增加在哪个地方。如果增加在根节点到左儿子的这条边上,那么只用增加一次。如果在第二层增加,那么就要增加次(左儿子的两条边各一次),如果在第三层增加,就要增加次,以此类推,所以为了增加的数量尽可能少,我们应该在根节点到左儿子的这条边上增加。右子树同理。
所以增加的总代价为,要让代价最小,那么就应该最小,即,因此最小代价就为。
可以发现,是每个左子树的叶子节点到根节点的最小距离,是每个右子树的叶子节点到根节点的最小距离。对于,如果稍微增大一些,那么这个绝对值就会减少。假设增加,可这意味着从第二层开始,至少要增加,这样代价反而会增加。虽然增加后会对当前这层的代价减少,但总的代价会增加,因此每次都应该取到根节点的最小距离。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 6 const int N = (1 << 11) + 10; 7 8 int n, ans; 9 int a[N]; 10 11 // dfs返回叶子节点到u的最小距离 12 int dfs(int u) { 13 if (u << 1 > (1 << n + 1) - 1) return 0; // 不存在左儿子,什么是叶子节点 14 15 int l = dfs(u << 1) + a[u << 1]; // 求左子树的叶子结点到u的距离 16 int r = dfs(u << 1 | 1) + a[u << 1 | 1];// 求右子树的叶子结点到u的距离 17 ans += abs(l - r); 18 19 return max(l, r); // l和r的最大距离就是u到叶子节点的最小距离 20 } 21 22 int main() { 23 scanf("%d", &n); 24 25 int m = (1 << n + 1) - 1; 26 for (int i = 2; i <= m; i++) { 27 scanf("%d", a + i); 28 } 29 30 dfs(1); 31 printf("%d", ans); 32 33 return 0; 34 }
参考资料
AcWing 4312. 出现次数(AcWing杯 - 周赛):https://www.acwing.com/video/3729/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16000030.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2021-03-13 图解带头节点的单链表的反转操作