题解:AT_abc395_g [ABC395G] Minimum Steiner Tree 2

Problem

题目给定一个完全图,其中每条边的权重由矩阵 \(C\) 给出,且满足 \(C_{i,i}=0\)\(C_{i,j}=C_{j,i}\)。要求构造一个好图,即从原图中删除部分边和顶点后,剩下的图是连通的且包含以下顶点:

  • 固定的 \(1,2,\dots,K\)
  • 以及查询中的两个额外顶点 \(s\)\(t\)(其中 \(s,t \in \{K+1,\dots,N\}\)\(s\neq t\))。

要求最小化好图中边权的总和。

Solution

这实际上是一个带有少量终端点(固定点)的 Steiner Tree 问题,并且每个查询要求额外连接两个指定的顶点。

由于图为完全图且任意两点之间都有直接连边,且 \(N\) 特别小,所以首先使用 Floyd 预处理出所有点对之间的最短距离,这样在后续动态规划中使用的边权已经是最优的。

对于每个额外顶点 \(s\)(范围为 \(K\)\(N-1\)),将终端集合设为:

  • 固定顶点 \(1,2,\dots,K\)(下标 \(0\)\(K-1\))。
  • 以及当前选择的顶点 \(s\)(作为第 \(K+1\) 个终端)。

令终端数为 \(m = K + 1\),定义状态:

\[dp[\text{mask}][v] = \text{连接 mask 中所有终端且最后在顶点 } v \text{ 的最小费用} \]

初始状态为:对于只包含一个终端(单个 \(1\)\(\text{mask}\)),直接赋值为该终端到各顶点的最短距离。

枚举每个 \(\text{mask}\) 的所有子掩码,将 \(\text{mask}\) 拆分为两个不相交的子集 \(sub\)\(ot\),并更新状态:

\[dp[\text{mask}][v] = \min\{dp[sub][v] + dp[ot][v]\} \]

对于当前状态 \(dp[\text{mask}][v]\),考虑从顶点 \(v\) 出发经过一条边到达顶点 \(u\),更新:

\[dp[\text{mask}][u] = \min\{dp[\text{mask}][u],\ dp[\text{mask}][v] + d(v, u)\} \]

最终对于每个选定的 \(s\) 和所有可能的 \(t\)(且 \(t \neq s\)),答案为:

\[\min_{v}\{ dp[(1<<m)-1][v] + d(v, t) \} \]

预处理所有可能的 \(s\)\(t\) 后,直接回答每个查询。

Code

posted @ 2025-03-04 18:12  薛儒浩  阅读(149)  评论(0)    收藏  举报