#lydlx05x0E21dc. Islands and Bridges 岛和桥

Islands and Bridges 岛和桥

No testdata at current.

题目描述

给定一个地图,地图中包含很多岛和连接它们的桥。

汉密尔顿路径是指沿着桥访问每个岛屿恰好一次的路径。

在我们的地图上的每个岛都具有一个权值,它是一个正整数。

假设一共有 nn 个岛,第 ii 个岛的权值为 ViV_i

现在规定一个汉密尔顿路径的总价值为以下三个价值的和:

  1. 每个岛屿的权值之和。
  2. 汉密尔顿路径中,每一条边连接的相邻岛屿的权值乘积之和。
  3. 如果在汉密尔顿路径中存在相邻的三个岛屿可以构成环形,则将所有满足条件的相邻岛屿三元组权值的乘积相加求和。

任务一:请你找出汉密尔顿路径的总价值最大可以为多少。 任务二:请你找出满足最大总价值的汉密尔顿路径共有多少条。

输入格式

第一行包含整数 qq,表示共有 qq 组测试数据。

每组数据第一行包含两个整数 n,mn,m,分别表示小岛数和桥数。

第二行包含 nn 个不超过 100100 的正整数,表示每个岛屿的权值。

接下来 mm 行,每行包含两个整数 a,ba,b,表示岛 aa 和岛 bb 之间存在一个双向桥。

岛屿的编号从 11nn

输出格式

每组数据输出一行,两个整数,分别表示汉密尔顿路径的最大总价值,以及满足最大总价值的汉密尔顿路径条数。

如果不存在汉密尔顿路径,则输出 0 0

注意:将一条路径按相反的顺序输出而成的路径,视为与原路径是同一条路径。例如 1-2-33-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

样例解释

第一组数据

n=3,m=3n=3, m=3 权值:[2,2,2][2,2,2] 桥:1-2, 2-3, 3-1(完全图 K3K_3

汉密尔顿路径(访问所有节点恰好一次): 可能的路径(考虑顺序和逆序相同):

  1. 1-2-3
  2. 1-3-2
  3. 2-1-3(但逆序 3-1-2 与 2-3-1 等价?需要明确)

实际上,在 n=3n=3 的完全图中,汉密尔顿路径有 3!=63! = 6 条,但每一条路径与其逆序视为同一条,所以有 33 条不同的路径(起点终点不同的环排列)。

计算每条路径的价值:

路径 1-2-3

  1. 节点权值和:2+2+2=6
  2. 边权值乘积和:边(1,2):2×2=4;边(2,3):2×2=4;总和 8。
  3. 三元环:检查连续三个节点 (1,2,3) 是否构成环?即是否存在边 (1,3)。由于是完全图,存在边 (1,3),所以构成环。三元组乘积:2×2×2=8。

总价值 = 6 + 8 + 8 = 22。

路径 1-3-2

  1. 节点和:6
  2. 边乘积:边(1,3):2×2=4;边(3,2):2×2=4;总和 8。
  3. 三元环:(1,3,2) 存在边 (1,2),构成环,乘积 8。

总价值 = 22。

路径 2-1-3

  1. 节点和:6
  2. 边乘积:边(2,1):4;边(1,3):4;总和 8。
  3. 三元环:(2,1,3) 存在边 (2,3),构成环,乘积 8。

总价值 = 22。

所有路径价值均为 22,且共有 3 条不同的路径,输出 22 3

第二组数据

n=4,m=6n=4, m=6(完全图 K4K_4) 权值:[1,2,3,4][1,2,3,4]

汉密尔顿路径数量:4!/2=124!/2 = 12 条(因为逆序相同)。

需要计算每条路径的价值,并找出最大值和对应路径数。

计算一条路径:例如 1-2-3-4

  1. 节点和:1+2+3+4=10
  2. 边乘积和:1×2 + 2×3 + 3×4 = 2+6+12=20
  3. 三元环检查:
    • 三元组 (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:

  1. 节点和:10
  2. 边乘积:1×3 + 3×2 + 2×4 = 3+6+8=17
  3. 三元环:
    • (1,3,2):边(1,2)存在,乘积 6
    • (3,2,4):边(3,4)存在,乘积 24 总和 30。 总价值 = 10+17+30 = 57。

路径 4-1-2-3:

  1. 节点和:10
  2. 边乘积:4×1 + 1×2 + 2×3 = 4+2+6=12
  3. 三元环:
    • (4,1,2):边(4,2)存在,乘积 8
    • (1,2,3):边(1,3)存在,乘积 6 总和 14。 总价值 = 10+12+14 = 36。

似乎都不够 69。

可能路径 4-2-1-3:

  1. 节点和:10
  2. 边乘积:4×2 + 2×1 + 1×3 = 8+2+3=13
  3. 三元环:
    • (4,2,1):边(4,1)存在,乘积 8
    • (2,1,3):边(2,3)存在,乘积 6 总和 14。 总价值 = 10+13+14 = 37。

还是不对。

也许最大值 69 来自路径 4-1-3-2?

  1. 节点和:10
  2. 边乘积:4×1 + 1×3 + 3×2 = 4+3+6=13
  3. 三元环:
    • (4,1,3):边(4,3)存在,乘积 12
    • (1,3,2):边(1,2)存在,乘积 6 总和 18。 总价值 = 10+13+18 = 41。

不是。

可能我算错了。让我们直接按照公式计算:

总价值 = 节点和 + 边乘积和 + 三元环乘积和。

对于完全图 K4K_4,任何路径的节点和固定为 10。

边乘积和取决于路径中相邻节点的权值乘积。

三元环乘积和取决于连续三个节点是否构成三角形(即中间节点与首尾节点是否都有边),由于完全图,任何三个节点都构成三角形,所以只要路径长度 ≥3,每个连续三元组都贡献乘积。

因此,对于路径 p1,p2,p3,p4p_1, p_2, p_3, p_4,总价值 =

$$\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 是同一路径,所以只算一条。

数据范围

  • 2n132 \le n \le 13
  • 1mn(n1)21 \le m \le \frac{n(n-1)}{2}
  • 权值不超过 100

算法分析

由于 n13n \le 13,可以使用状态压缩动态规划枚举所有汉密尔顿路径。

状态定义

dp[mask][i][j]dp[mask][i][j] 表示当前已访问节点集合为 maskmask(二进制位表示),路径的最后两个节点为 iijj(即最后一条边是 (i,j)(i,j))时的最大总价值,以及达到该价值的路径条数。

其中 maskmask 包含 iijj

转移

考虑下一个节点 kk,需要满足:

  • kmaskk \notin mask
  • 存在边 (j,k)(j,k)

新的状态 mask=mask{k}mask' = mask \cup \{k\},最后两个节点为 (j,k)(j,k)

价值增加:

  1. 节点 kk 的权值 VkV_k(节点和部分,但节点和是所有节点权值和,可以在最后统一加,或者每次加新节点时加上。注意第一个节点和第二个节点需要加两次?实际上节点和是所有节点权值之和,与路径顺序无关,所以可以提前计算总和,不需要在 DP 中累加)。
  2. (j,k)(j,k) 的乘积 Vj×VkV_j \times V_k
  3. 三元环:如果存在边 (i,k)(i,k),则增加三元组乘积 Vi×Vj×VkV_i \times V_j \times V_k

因此,转移时的价值增量为:

$$\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 )$$

但注意:节点和部分,第一个节点之前没有边和三元环,需要特殊处理。我们可以初始化状态为两个节点的路径。

初始化

枚举所有边 (i,j)(i,j),初始状态 mask=(1<<i)(1<<j)mask = (1<<i) | (1<<j),最后两个节点为 (i,j)(i,j)。价值 = Vi+Vj+Vi×VjV_i + V_j + V_i \times V_j(节点和 + 边乘积),没有三元环。

最终答案

maskmask 包含所有节点(即 mask=(1<<n)1mask = (1<<n)-1)时,更新全局最大值和方案数。

注意:路径反向视为同一条,所以最后方案数需要除以 2?但我们在 DP 中已经区分了方向,因为状态记录了最后两个节点,方向是固定的。但最终统计时,每条路径会从两个方向各被计算一次(起点和终点互换),所以最终方案数应除以 2。

复杂度

状态数:2n×n×n2^n \times n \times n,对于 n=13n=13213=81922^{13}=8192n2=169n^2=169,总状态数约 1.38×1061.38 \times 10^6,每个状态转移最多 nn 次,总操作约 1.38×106×131.8×1071.38 \times 10^6 \times 13 \approx 1.8 \times 10^7,可接受。

实现细节

  • 用邻接矩阵存边,方便判断 edge[i][k]edge[i][k]
  • DP 数组存储两个值:最大价值和对应路径数。
  • 转移时,如果新价值大于当前记录,则更新价值和方案数;如果等于当前记录,则方案数累加。
  • 最终答案需要检查所有 maskmask 满的状态,取最大值。

节点和的处理

节点和与路径顺序无关,所以我们可以预先计算所有节点权值之和 sumVsumV,然后 DP 中只计算边乘积和三元环乘积,最后总价值 = sumVsumV + 最大(边乘积和+三元环乘积)。

但初始化时,两个节点的路径价值 = Vi+Vj+Vi×VjV_i + V_j + V_i \times V_j,其中 Vi+VjV_i+V_j 是节点和的一部分,而 sumVsumV 包含所有节点,所以不能简单加 sumVsumV

因此,在 DP 中,我们统一计算额外价值(即边乘积和三元环乘积),而节点和单独加。

dpdp 存储额外价值(边乘积和三元环乘积之和)的最大值。

初始化:对于边 (i,j)(i,j),额外价值 = Vi×VjV_i \times V_j

转移:$\Delta = V_j \times V_k + ( \text{if edge}(i,k) \text{ then } V_i \times V_j \times V_k \text{ else } 0 )$。

最终总价值 = sumV+dpfullsumV + dp_{full}

方案数

方案数需要在 DP 中同时记录。

样例验证

对于第一组数据,n=3n=3,权值全 2。 sumV=6sumV = 6

初始化边:

  • (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,sumV=10sumV=10,所以额外价值 59),方案数 1。

总结

本题是状态压缩 DP 的典型应用,需要仔细处理价值计算和方案统计。由于 nn 较小,可以直接枚举所有状态。