【发布时间】:2015-05-11 16:25:20
【问题描述】:
您好,感谢您阅读本文。
给定一个由 N 个顶点和 e 个边组成的无向树以及相关的奖励点 P_e,起始顶点:s 和一个整数:M
然后我们必须找到: 从 s 开始,遍历 M 条边,我们可以获得的最大点数。
一条边可以被遍历多次。
请指导我正确的方向来解决这个问题。
【问题讨论】:
您好,感谢您阅读本文。
给定一个由 N 个顶点和 e 个边组成的无向树以及相关的奖励点 P_e,起始顶点:s 和一个整数:M
然后我们必须找到: 从 s 开始,遍历 M 条边,我们可以获得的最大点数。
一条边可以被遍历多次。
请指导我正确的方向来解决这个问题。
【问题讨论】:
首先让我们观察一下,如果您将在最优解中多次遍历某些边,那么所有这些边将获得相同的奖励(否则越多次遍历奖励越大的边会更有利可图)。因此,在不失慷慨的情况下,我们可以说您将准确地遍历一条边多次。
其次,您将多次遍历的边将是您最佳路径中所有边中奖励最大的边。否则再次遍历奖励更大的路径会更有利可图,并且路径将不是最优的。因此,您将多次遍历的边将是您路径中的最后一条边。
所以这里有一个简单的算法:遍历树中距离起点不远于 M 的所有顶点,找到从 s 到没有边重复的每个顶点的奖励点的总和(这个数字将以唯一的方式确定,因为在树中的每一对顶点之间只有一条路径),并使用剩余的 M 条边来遍历奖励最大的边(每次我们认为这条边是我们的最后一条边)在当前路径中使用)。
这是一个伪代码:
ans = -INF
traverse(vertex, pathLength, pathReward, lastEdge) {
if (visited(vertex)) // Do not visit a vertex twice
return;
if (pathLength > 0)
ans = max(ans, pathReward + (M - pathLength) * lastEdge)
if (pathLength == M) // We cannot go farther than M edges
return;
for (vertex, nextVertex) in edges:
edgeReward = edgeReward(vertex, nextVertex)
traverse(nextVertex, pathLength + 1, pathReward + edgeReward, edgeReward)
}
你会打电话给
traverse(0, 0, 0, -INF)
然后从ans 获取结果。
【讨论】: