LCP 16-游乐园的游览计划
又到了一年一度的春游时间,小吴计划去游乐场游玩 1 天,游乐场总共有 N
个游乐项目,编号从 0
到N-1
。小吴给每个游乐项目定义了一个非负整数值 value[i]
表示自己的喜爱值。两个游乐项目之间会有双向路径相连,整个游乐场总共有 M
条双向路径,保存在二维数组 edges
中。 小吴计划选择一个游乐项目 A
作为这一天游玩的重点项目。上午小吴准备游玩重点项目 A
以及与项目A
相邻的两个项目 B
、C
(项目A
、B
与C
要求是不同的项目,且项目B
与项目C
要求相邻),并返回 A
,即存在一条A-B-C-A
的路径。 下午,小吴决定再游玩重点项目 A
以及与A
相邻的两个项目B'
、C'
,(项目A
、B'
与C'
要求是不同的项目,且项目B'
与项目C'
要求相邻),并返回 A
,即存在一条A-B'-C'-A
的路径。下午游玩项目 B'
、C'
可与上午游玩项目B
、C
存在重复项目。
小吴希望提前安排好游玩路径,使得喜爱值之和最大。请你返回满足游玩路径选取条件的最大喜爱值之和,如果没有这样的路径,返回 0
。
注意:一天中重复游玩同一个项目并不能重复增加喜爱值了。例如:上下午游玩路径分别是 A-B-C-A
与A-C-D-A
那么只能获得 `value[A]
- value[B] + value[C] + value[D]` 的总和。
示例 1:
输入:
edges = [[0,1],[1,2],[0,2]], value = [1,2,3]
输出:
6
解释:喜爱值之和最高的方案之一是 0->1->2->0 与 0->2->1->0 。重复游玩同一点不重复计入喜爱值,返回1+2+3=6
示例 2:
输入:
edges = [[0,2],[2,1]], value = [1,2,5]
输出:
0
解释:无满足要求的游玩路径,返回 0
示例 3:
输入:
edges = [[0,1],[0,2],[0,3],[0,4],[0,5],[1,3],[2,4],[2,5],[3,4],[3,5],[4,5]], value = [7,8,6,8,9,7]
输出:
39
解释:喜爱值之和最高的方案之一是 3->0->1->3 与 3->4->5->3 。喜爱值最高为 7+8+8+9+7=39
限制:
3 <= value.length <= 10000
1 <= edges.length <= 10000
0 <= edges[i][0],edges[i][1] < value.length
0 <= value[i] <= 10000
edges中没有重复的边
edges[i][0] != edges[i][1]
题意概述:
在图中找到两个三角形(边可以重复),两个三角形至少需要一个点相连,使得最终所有点的权值和最大。
考点一:找三角形
我们知道点数和边数是一个数量级,这里我们就用 N 统一代替,三角形最多有 N\sqrt{N 个,如何遍历他们呢?
- 假如某个顶点 v 的度数没有超过 \sqrt{N,枚举和 v 相邻的两个顶点,并用哈希表查看这两个顶点是否相连。所有这类点的处理复杂度为:\sum_v deg(v)^2 \leq \sum_v deg(v)\times\sqrt{N} = \sqrt{N} \times M = N\sqrt{N。
- 对于剩下所有度数超过 \sqrt{N 的点,这类点的个数最多有 \sqrt{N 个,这是因为所有点度数之和等于 2M。那么对于这些点,枚举任意三个并利用哈希表查看是否有边相连。所有这类点的处理复杂度为:\sqrt{N}^3=N\sqrt{N。
对于一个三角形,如果有某一个顶点度数小于等于 \sqrt{N,可以通过第一种办法得到。如果所有点度数都超过 \sqrt{N,那么第二种方法可以找到。所以能够找到所有的三角形。注意这里两条边的查询一定要用 O(1) 的哈希表,而不能使用 O(\log N) 的二叉树,不然复杂度会多一个 \log。
考点二:三角形拼接
三角形的拼接有三种可能:
- 两个三角形完全重合
- 两个三角形重合一条边
- 两个三角形重合一条点
对于第一种可能,我们找所有三角形时记录最大三角形的值;对于第二种可能,通过枚举一条边,计算第一和第二大三角形的和;我们重点讨论最后一种可能的求解方案,首先有下列性质。
性质:枚举一个点 x 作为两个三角形的重合点,假设它构成的最大三角形是 \triangle xab;那么另两个点 a、b 都出现在点 x 作为两个三角形重合点的最佳方案中
证明过程:
三角形 \triangle xab 是包含点 x 的最大三角形,考虑最优解是以 x 为中心点的两个三角形 \triangle xpq 和 \triangle xrt
- 如果点 a 和 b 都不出现在 pqrt 中,那么直接将其中一个三角形换成 \triangle xab 可以得到更优解
- 如果点 a 和 b 只有一个出现在 pqrt 中,那么将对应的那个三角形换成 \triangle xab 可以得到最优解
所以点 a 和 b 一定同时出现在点 x 作为两个三角形重合点的最佳方案 pqrt 中
这里最佳方案中点 a 和 b 同时出现分两种情况讨论:
- 如果点 a 和 b 出现在一个三角形中,那么直接用 \triangle xab 和另一个和 x 相邻的三角形一一组合
- 如果点 a 和 b 不在一个三角形中,那么一定是 xa 这条边构成的三角形 + xb 这条边构成的三角形。这种情况,记录两条边出现的权值最大的三个三角形,然后一一尝试拼接即可。(这里记录Top3是因为Top2三角形可能存在重复的点)
综上,就变成枚举中间点 x,包含点 x 的最大三角形 \triangle xab 和所有包含 x 的三角形一一组合,以及包含边 xa 和边 xb 的最大的三个三角形一一组合,计算最终结果。(也可以推导出点 x 的 Top2 三角形 和所有包含 x 的三角形一一组合,证明方法类似)
1 | class Solution { |
1 | import collections |
复杂度分析
时间复杂度:O(N\sqrt{N}),N 是顶点和边的数量级。
空间复杂度:O(N)。