📅  最后修改于: 2023-12-03 14:55:38.667000             🧑  作者: Mango
树的所有对之间的最小边权的乘积指的是,对于一棵树,找到所有节点对之间的距离的最小值,把这些最小距离相乘得到的结果。
解决这个问题的方法通常是基于动态规划。我们可以定义一个双重循环的二维数组 $dp_{i,j}$,其中 $dp_{i,j}$ 表示节点 $i$ 到节点 $j$ 的最小距离。
根据树的性质,我们可以发现,对于每一个节点 $i$,可以把整个树分为两个部分:以 $i$ 为根的子树和不以 $i$ 为根的子树。于是,我们可以把问题分解为两个子问题:计算 $i$ 到 $j$ 的距离,或者 $i$ 到 $j$ 经过 $i$ 的祖先节点的距离。
于是,我们可以使用下面的状态转移方程来计算 $dp_{i,j}$:
$dp_{i,j} = \min{dp_{i,k} + dp_{k,j}} \quad (k \in \operatorname{lca}(i,j))$
其中,$\operatorname{lca}(i,j)$ 表示节点 $i$ 和节点 $j$ 的最近公共祖先节点集合。
下面是 Python 实现代码的示例,使用了前缀和优化和 DFS 迭代实现。
def dfs(u, fa, d, f):
f[u] = 1
for v, w in d[u]:
if v == fa:
continue
dfs(v, u, d, f)
f[u] += f[v]
f[u] %= mod
f[u] += f[v] * (n - f[v])
f[u] %= mod
sumd[u] += sumd[v] + f[v] * w
sumd[u] %= mod
n = int(input())
d = [list() for i in range(n + 1)]
sumd = [0] * (n + 1)
mod = 998244353
for i in range(1, n):
u, v, w = map(int, input().split())
d[u].append((v, w))
d[v].append((u, w))
dfs(1, 0, d, sumd)
ans = 0
for i in range(2, n + 1):
ans += sumd[i] * i
ans %= mod
print(ans)