hdu7166

题面

给定一个无向图,图上每条边 \(x_i,y_i\) 都有两个边权 \(a_i,b_i\) ,现在 A,B 要在上面玩一个游戏。

首先 A 要给每个边确定其真正权值是 \(a_i\) 还是 \(b_i\) ,其中是 \(a_i\) 的边的个数恰好是 \(k\)

之后 B 会在其中选一个最小生成树,A 希望选出来的最小生成树权值和最大。

对每一个 \(k\in[0,m]\) 求出答案。

数据范围:\(n\le 9,m\le 30\)

题解

因为题目其实是让要我们求所有选法中最小生成树的最大值,所以我们肯定往求最小生成树的算法上考虑。(而不是爆搜!!!!)

肯定是先考虑 kruskal ,按边权从小到大依次考虑 \(x_i,y_i\) 是否联通。

但是我们还是没法处理每个边是选了 \(a_i\) 还是 \(b_i\) (这里默认 \(a_i<b_i\))。

这里就有一个套路,如果选 \(a_i\) 了后 \(b_i\) 不会带来额外影响,那么我们就可以把边拆成 \((x_i,y_i,a_i)\)\((x_i,y_i,b_i)\)

下面把\((x_i,y_i,a_i)\) 看作 \(A\) 边, \((x_i,y_i,b_i)\) 看作 \(B\) 边。

什么意思?

在这里,我们按小到大去考虑每条边,所以 \(A\) 边肯定会比 \(B\) 边先考虑到,那么如果 \(A\) 边被选了,那么之后再碰到 \(B\) 边,它肯定不会对当前的最小生成树产生贡献(因为 \(A,B\) 边有同样的 \(x_i,y_i\) ,所以即使 \(x_i,y_i\) 不连通,那么也是在 \(A\) 边的时候就连上了)。

所以我们的决策就在 \(A\) 边上就行了(考虑选不选 \(A\) 边)。

而怎么分辨这一条边是 \(A\) 边还是 \(B\) 边呢?拆成 \((x_i,y_i,a_i,1)\)\((x_i,y_i,b_i,0)\) 即可。

至于怎么维护点之间的联通情况,状压并查集即可。

所以就有设dp \(f_{i,j,k}\) 表示考虑到第 \(i\) 个边,当前选了 \(j\)\(A\) 边, 且并查集状态是 \(k\) ,直接看当前的边转移即可。

复杂度是 \(O(m^2B(9))\)\(B(x)\) 是贝尔数。

启发

  • 对于要决策是 \(A\) 还是 \(B\) 的时候,如果选了 \(A\) 后选 \(B\) 对答案无影响,那么就可以按上面的方法拆操作。多个决策也同样适用。
posted @ 2022-07-27 22:35  qwq_123  阅读(54)  评论(0编辑  收藏  举报