我在接受采访时被问到这个问题,并且在分配的时间里努力正确回答。尽管如此,我认为这是一个有趣的问题,我以前没见过。
假设你有一棵树,根可以打电话(在电话上)每个孩子的孩子,当孩子接到电话时,他可以给每个孩子打电话等等。问题是每次电话都必须在多轮,我们需要尽量减少拨打电话所需的轮数。例如,假设您有以下树:
A / \ / \ B D | | C
一种解决方案是A在第一轮呼叫D,A在第二轮呼叫B,B在第三轮呼叫C。最佳解决方案是A在第一轮呼叫B,A呼叫D和B在第二轮呼叫C.
请注意,A不能在同一轮中同时调用B和D,任何节点也不能在同一轮中调用多个子节点。但是,具有不同父节点的多个节点可以同时调用。例如,给定树:
A / | \ / | \ B C D /\ | / \ | E F G
我们可以有一个序列(其中 - 分隔轮次),例如:
A B - B E,A D - B F,A C,D G
(A呼叫B第一轮,B呼叫E,A呼叫D秒,......)
我假设可以使用某种类型的动态编程,但我不确定采用哪种方向。我最初的倾向是使用DFS按顺序排序从根到叶的最长路径,但是当涉及到实际进行调用的节点时,我不确定如何在给定任何树的情况下实现最优性,而不是如何输出最优调用将产生的路径(即在第一个示例中我们可以输出
A B - B C,A D
答案 0 :(得分:2)
我认为这样的事情可以得到最佳解决方案:
它在树上进行动态编程,你可以像这样递归地实现它:
int f(node v)
{
int s = 0;
for each u in v.children
{
d[u] = f(u)
}
sort d and rank its values in r (r for the maximum u would be 1)
for each u in v.children
{
s = max(s, d[u] + r[u] + 1)
}
return s
}
祝你好运!