P17485 湖上的前线基地 题解
显然,本质上是最小生成树.
我们考虑怎么跑克鲁斯卡尔或者Prim.
首先考虑prim.
prim的方法是随便选一个点是初始状态.然后吧与当前的树连接的点中最近的点加入到树中.
但是问题是我们的边是n^2个的,每个点到其他点总是存在一条边.
所以常规的prim是不行的.
我们考虑克鲁斯卡尔.
我们可以先给a排序,然后便利每个a的元素.然后看能否让点与另外一个点的按位与的结果为当前的a.
但是这个做法对于a的每一个向都需要(2n)2枚举每个点对.
这显然是无法接受的.
下面是cat_cat的思路
我们刚才是从已有算法出发.
我们现在考虑不依靠已有算法.
我们从点考虑.
我们考虑,对于一个点,我们怎么把他加入到树中.
由于任意一个二进制状态总是一个点.
贪心的 我们可以考虑,对于这个点的编号\(u\),我们枚举\(u\)的子集,选举\(u\)的子集中的点中,a的值最小的那个.然后连接边.
但是问题在与,诺\(u\)的子集中,最小的就是\(u\)自己怎么办? 那么我们要与u的超集连边.
我们考虑怎么选取超集.
显然,对于当前选取的集合\(x\),超集\(y\),总存在\(z\),使得 \(x and z=y\)
我们考虑找一个公共的\(z\),使得对于每个\(f[i]=i\),满足\(i and (i|z)=i\),且\(i|z!=i\)
以下是一个题解思路
我们对可卢瑟卡尔做优化
我们不需要枚举每对\(u,v\) 只需要枚举当前\(a\)的值的超集就行了

浙公网安备 33010602011771号