解析
当a和b满足\(a = b \times prime\)时,我们说a,b有冲突关系,将所有数看成是图中的顶点,那么a和b有冲突关系,就在a,b之间连一条边。题目是:给定一些数,从这些数中选出一些数组成一个集合,使这个集合中的每两个数都没有冲突关系,也就是每两个顶点之间都没有边,问这个集合最多可以有多少个数。
任意一个整数可以分解为多个素数因子的乘积,而只有分解后,素数因子数为奇数和偶数的两个数才有可能有冲突,因为一个素数因子数为奇数的数a只有乘上两个素数才能成为一个新的素数因子为奇数的数b,显然a与b不存在冲突关系,素数因子数为偶数的两个数同理。所以我们可以根据素数因子数的奇偶来将所有数划分为两个集合X和Y,X中的元素和Y中的元素可能有边,而同一个集合中的元素没有边,显然这是一个二分图。
再看这个问题,其实就是求最大独立集的元素个数。最大独立集就是选取最多的点组成一个集合,使任意所选两点均不相连。
有这么一个公式:最大独立集的元素个数 = 顶点数 - 最大匹配数。这里的最大匹配数就是二分图的最大匹配。所以我们只需要找出上述二分图的最大匹配数,用顶点数减去最大匹配数就是答案。注意二分图顶点的个数多达4e4,用匈牙利算法会严重超时,我们使用优化的算法——Hopcroft-Krap算法,邻接表存图时,时间复杂度是\(O(V\sqrt{E})\)。HK算法可以参考我的另一篇文章《求二分图最大匹配——Hopcroft-Krap算法》。
求最大独立集还有另一种求法,是求这个图的补图的最大团,但是这种方法时间复杂度很高,我们不采用这种方法解这道题
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e4 + 5;
const int maxm = 5e5 + 5;
const int inf = 0x3f3f3f3f