#lydlx05x0E21dc. Islands and Bridges 岛和桥
Islands and Bridges 岛和桥
No testdata at current.
题目描述
给定一个地图,地图中包含很多岛和连接它们的桥。
汉密尔顿路径是指沿着桥访问每个岛屿恰好一次的路径。
在我们的地图上的每个岛都具有一个权值,它是一个正整数。
假设一共有 个岛,第 个岛的权值为 。
现在规定一个汉密尔顿路径的总价值为以下三个价值的和:
- 每个岛屿的权值之和。
- 汉密尔顿路径中,每一条边连接的相邻岛屿的权值乘积之和。
- 如果在汉密尔顿路径中存在相邻的三个岛屿可以构成环形,则将所有满足条件的相邻岛屿三元组权值的乘积相加求和。
任务一:请你找出汉密尔顿路径的总价值最大可以为多少。 任务二:请你找出满足最大总价值的汉密尔顿路径共有多少条。
输入格式
第一行包含整数 ,表示共有 组测试数据。
每组数据第一行包含两个整数 ,分别表示小岛数和桥数。
第二行包含 个不超过 的正整数,表示每个岛屿的权值。
接下来 行,每行包含两个整数 ,表示岛 和岛 之间存在一个双向桥。
岛屿的编号从 到 。
输出格式
每组数据输出一行,两个整数,分别表示汉密尔顿路径的最大总价值,以及满足最大总价值的汉密尔顿路径条数。
如果不存在汉密尔顿路径,则输出 0 0。
注意:将一条路径按相反的顺序输出而成的路径,视为与原路径是同一条路径。例如 1-2-3 和 3-2-1 为同一条路径。
样例
2
3 3
2 2 2
1 2
2 3
3 1
4 6
1 2 3 4
1 2
1 3
1 4
2 3
2 4
3 4
22 3
69 1
样例解释
第一组数据
权值: 桥:1-2, 2-3, 3-1(完全图 )
汉密尔顿路径(访问所有节点恰好一次): 可能的路径(考虑顺序和逆序相同):
- 1-2-3
- 1-3-2
- 2-1-3(但逆序 3-1-2 与 2-3-1 等价?需要明确)
实际上,在 的完全图中,汉密尔顿路径有 条,但每一条路径与其逆序视为同一条,所以有 条不同的路径(起点终点不同的环排列)。
计算每条路径的价值:
路径 1-2-3:
- 节点权值和:2+2+2=6
- 边权值乘积和:边(1,2):2×2=4;边(2,3):2×2=4;总和 8。
- 三元环:检查连续三个节点 (1,2,3) 是否构成环?即是否存在边 (1,3)。由于是完全图,存在边 (1,3),所以构成环。三元组乘积:2×2×2=8。
总价值 = 6 + 8 + 8 = 22。
路径 1-3-2:
- 节点和:6
- 边乘积:边(1,3):2×2=4;边(3,2):2×2=4;总和 8。
- 三元环:(1,3,2) 存在边 (1,2),构成环,乘积 8。
总价值 = 22。
路径 2-1-3:
- 节点和:6
- 边乘积:边(2,1):4;边(1,3):4;总和 8。
- 三元环:(2,1,3) 存在边 (2,3),构成环,乘积 8。
总价值 = 22。
所有路径价值均为 22,且共有 3 条不同的路径,输出 22 3。
第二组数据
(完全图 ) 权值:
汉密尔顿路径数量: 条(因为逆序相同)。
需要计算每条路径的价值,并找出最大值和对应路径数。
计算一条路径:例如 1-2-3-4
- 节点和:1+2+3+4=10
- 边乘积和:1×2 + 2×3 + 3×4 = 2+6+12=20
- 三元环检查:
- 三元组 (1,2,3):检查边(1,3)是否存在?完全图存在,乘积 1×2×3=6
- 三元组 (2,3,4):检查边(2,4)是否存在?存在,乘积 2×3×4=24 总和 30。 总价值 = 10+20+30 = 60。
但输出是 69,说明有更高的路径。
尝试路径 1-3-2-4:
- 节点和:10
- 边乘积:1×3 + 3×2 + 2×4 = 3+6+8=17
- 三元环:
- (1,3,2):边(1,2)存在,乘积 6
- (3,2,4):边(3,4)存在,乘积 24 总和 30。 总价值 = 10+17+30 = 57。
路径 4-1-2-3:
- 节点和:10
- 边乘积:4×1 + 1×2 + 2×3 = 4+2+6=12
- 三元环:
- (4,1,2):边(4,2)存在,乘积 8
- (1,2,3):边(1,3)存在,乘积 6 总和 14。 总价值 = 10+12+14 = 36。
似乎都不够 69。
可能路径 4-2-1-3:
- 节点和:10
- 边乘积:4×2 + 2×1 + 1×3 = 8+2+3=13
- 三元环:
- (4,2,1):边(4,1)存在,乘积 8
- (2,1,3):边(2,3)存在,乘积 6 总和 14。 总价值 = 10+13+14 = 37。
还是不对。
也许最大值 69 来自路径 4-1-3-2?
- 节点和:10
- 边乘积:4×1 + 1×3 + 3×2 = 4+3+6=13
- 三元环:
- (4,1,3):边(4,3)存在,乘积 12
- (1,3,2):边(1,2)存在,乘积 6 总和 18。 总价值 = 10+13+18 = 41。
不是。
可能我算错了。让我们直接按照公式计算:
总价值 = 节点和 + 边乘积和 + 三元环乘积和。
对于完全图 ,任何路径的节点和固定为 10。
边乘积和取决于路径中相邻节点的权值乘积。
三元环乘积和取决于连续三个节点是否构成三角形(即中间节点与首尾节点是否都有边),由于完全图,任何三个节点都构成三角形,所以只要路径长度 ≥3,每个连续三元组都贡献乘积。
因此,对于路径 ,总价值 =
$$\sum_{i=1}^4 V_{p_i} + \sum_{i=1}^3 V_{p_i} V_{p_{i+1}} + \sum_{i=1}^2 V_{p_i} V_{p_{i+1}} V_{p_{i+2}}$$我们需要最大化这个表达式。
暴力枚举所有 12 条路径,计算得到最大值 69,对应路径可能是 4-3-1-2?计算:
- 节点和:4+3+1+2=10
- 边乘积:4×3 + 3×1 + 1×2 = 12+3+2=17
- 三元环乘积:4×3×1 + 3×1×2 = 12+6=18 总价值 = 10+17+18=45,不对。
可能路径 4-2-3-1:
- 节点和:10
- 边乘积:4×2 + 2×3 + 3×1 = 8+6+3=17
- 三元环乘积:4×2×3 + 2×3×1 = 24+6=30 总价值 = 10+17+30=57。
还是不对。
实际上,输出 69,说明有一条路径总价值为 69。让我们反推:
设路径为 a-b-c-d。 总价值 = (a+b+c+d) + (ab+bc+cd) + (abc+bcd) = a+b+c+d + ab+bc+cd + abc+bcd。
代入权值 1,2,3,4 的不同排列。
计算所有排列(12种): 我们写程序计算,但这里手工尝试几个:
- 1-2-3-4:=10 + (2+6+12) + (6+24) =10+20+30=60
- 1-2-4-3:=10+(2+8+12)+(8+24)=10+22+32=64
- 1-3-2-4:=10+(3+6+8)+(6+16)=10+17+22=49
- 1-3-4-2:=10+(3+12+8)+(12+24)=10+23+36=69 ← 找到了!
验证:路径 1-3-4-2 节点和:1+3+4+2=10 边乘积:1×3=3, 3×4=12, 4×2=8,总和 23 三元环乘积:1×3×4=12, 3×4×2=24,总和 36 总价值 = 10+23+36=69。
因此最大值 69,只有这一条路径?输出 69 1,说明只有一种(不考虑逆序)。
注意:逆序 2-4-3-1 与 1-3-4-2 是同一路径,所以只算一条。
数据范围
- 权值不超过 100
算法分析
由于 ,可以使用状态压缩动态规划枚举所有汉密尔顿路径。
状态定义
设 表示当前已访问节点集合为 (二进制位表示),路径的最后两个节点为 和 (即最后一条边是 )时的最大总价值,以及达到该价值的路径条数。
其中 包含 和 。
转移
考虑下一个节点 ,需要满足:
- 存在边
新的状态 ,最后两个节点为 。
价值增加:
- 节点 的权值 (节点和部分,但节点和是所有节点权值和,可以在最后统一加,或者每次加新节点时加上。注意第一个节点和第二个节点需要加两次?实际上节点和是所有节点权值之和,与路径顺序无关,所以可以提前计算总和,不需要在 DP 中累加)。
- 边 的乘积 。
- 三元环:如果存在边 ,则增加三元组乘积 。
因此,转移时的价值增量为:
$$\Delta = V_k + V_j \times V_k + ( \text{if edge}(i,k) \text{ exists then } V_i \times V_j \times V_k \text{ else } 0 )$$但注意:节点和部分,第一个节点之前没有边和三元环,需要特殊处理。我们可以初始化状态为两个节点的路径。
初始化
枚举所有边 ,初始状态 ,最后两个节点为 。价值 = (节点和 + 边乘积),没有三元环。
最终答案
当 包含所有节点(即 )时,更新全局最大值和方案数。
注意:路径反向视为同一条,所以最后方案数需要除以 2?但我们在 DP 中已经区分了方向,因为状态记录了最后两个节点,方向是固定的。但最终统计时,每条路径会从两个方向各被计算一次(起点和终点互换),所以最终方案数应除以 2。
复杂度
状态数:,对于 ,,,总状态数约 ,每个状态转移最多 次,总操作约 ,可接受。
实现细节
- 用邻接矩阵存边,方便判断 。
- DP 数组存储两个值:最大价值和对应路径数。
- 转移时,如果新价值大于当前记录,则更新价值和方案数;如果等于当前记录,则方案数累加。
- 最终答案需要检查所有 满的状态,取最大值。
节点和的处理
节点和与路径顺序无关,所以我们可以预先计算所有节点权值之和 ,然后 DP 中只计算边乘积和三元环乘积,最后总价值 = + 最大(边乘积和+三元环乘积)。
但初始化时,两个节点的路径价值 = ,其中 是节点和的一部分,而 包含所有节点,所以不能简单加 。
因此,在 DP 中,我们统一计算额外价值(即边乘积和三元环乘积),而节点和单独加。
设 存储额外价值(边乘积和三元环乘积之和)的最大值。
初始化:对于边 ,额外价值 = 。
转移:$\Delta = V_j \times V_k + ( \text{if edge}(i,k) \text{ then } V_i \times V_j \times V_k \text{ else } 0 )$。
最终总价值 = 。
方案数
方案数需要在 DP 中同时记录。
样例验证
对于第一组数据,,权值全 2。 。
初始化边:
- (1,2): 额外价值 = 2×2=4
- (2,3): 4
- (3,1): 4
转移: 从状态 (1,2) 加节点 3:$\Delta = V_2×V_3 + (边(1,3)存在 ? V_1×V_2×V_3 : 0) = 4 + 8 = 12$。 总额外价值 = 4+12=16。 总价值 = 6+16=22。
其他路径类似,所有路径额外价值都是 16,总价值 22。 方案数:3 条路径。
第二组数据,需要 DP 计算得到最大值额外价值 59(因为总价值 69,,所以额外价值 59),方案数 1。
总结
本题是状态压缩 DP 的典型应用,需要仔细处理价值计算和方案统计。由于 较小,可以直接枚举所有状态。