算法题目——游历魔法王国
链接:https://www.nowcoder.com/questionTerminal/f58859adc39f4edc9cd8e40ba4160339
来源:牛客网
魔法王国一共有n个城市,编号为0~n-1号,n个城市之间的道路连接起来恰好构成一棵树。
小易现在在0号城市,每次行动小易会从当前所在的城市走到与其相邻的一个城市,小易最多能行动L次。
如果小易到达过某个城市就视为小易游历过这个城市了,小易现在要制定好的旅游计划使他能游历最多的城市,请你帮他计算一下他最多能游历过多少个城市(注意0号城市已经游历了,游历过的城市不重复计算)。
输入描述:
输入包括两行,第一行包括两个正整数n(2 ≤ n ≤ 50)
和L(1 ≤ L ≤ 100)
,表示城市个数和小易能行动的次数。
第二行包括n-1
个整数parent[i](0 ≤ parent[i] ≤ i)
, 对于每个合法的i(0 ≤ i ≤ n - 2)
,在(i+1)
号城市和parent[i]
间有一条道路连接。
输出描述:
输出一个整数,表示小易最多能游历的城市数量。
分析
题目经过抽象之后,意思是在一个树中进行遍历,经过指定步数,可以获取最长经过节点树量的路径。如果把这个树按照根节点进行悬挂,可能更好理解一些。虽然有些答案是从低向上生长,但是我还是重建了树,采用悬挂树来做的。
从这个根节点开始遍历,先判断左树深度大还是右树深度大,先遍历树深度大的那个节点。直到步数用完为止。
树的深度通过后序遍历很容易求出来,结果发现这样的答案只能通过60%。
45 73
0 0 0 1 0 0 3 5 6 8 7 9 1 10 1 2 15 6 8 11 14 17 8 14 3 21 23 3 21 15 12 5 21 31 11 13 7 17 20 26 28 16 36 26
错在这个用例上了。这个正确答案是41,通过简单的贪心算法只能得到39个城市。
后来看了解析也是看不太懂。总之之后看到正确答案中是求出来深度后直接获得最终答案。
假设我们已经求出了每一个节点的最大深度,用deep[i]来表示,树的最下面一层的深度是1。
显然,根节点到任意一个节点的最长路径=deep[0]-1。
以这条路径为基础,我们可以额外访问一些节点。但是每次访问完这些节点的时候,我们必须回来这个路径。这一来一回,每次访问一个节点都必须额外走两步,访问两个节点就必须走4步。
看图就容易明白一些:
image.png 【算法题目——游历魔法王国】参考代码
#include
#include
using namespace std;
vector > tree;
vector deep;
void calc_deep(int i)
{
int max_deep = 0;
for(auto j:tree[i])
{
calc_deep(j);
max_deep = max(deep[j], max_deep);
}
deep[i] = max_deep + 1;
}int main()
{
int n, L;
cin >> n >> L;
/* 建立树 */
tree.resize(n);
deep.resize(n);
for(int i=0;
i> num;
tree[num].push_back(i+1);
}
/* 计算深度 */
calc_deep(0);
// int validpath = min(deep[0] -1,L);
// cout << min(n, 1 + validpath + (L - validpath)/2) << endl;
int long_path = deep[0] - 1;
if(long_path > L)cout << L + 1;
else cout << 1 + long_path + (L - long_path)/2;
}
推荐阅读
- 急于表达——往往欲速则不达
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 2019-02-13——今天谈梦想()
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- Ⅴ爱阅读,亲子互动——打卡第178天
- 低头思故乡——只是因为睡不着
- 取名——兰
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议
- 画解算法(1.|画解算法:1. 两数之和)