题目链接:https://vjudge.net/problem/LightOJ-1356

题目大意:

  T个 test case,每个 test case 给出一个 N 个数的集合。请找出一个最大的子集,使得子集中的任何一个数除以子集中的任意的另一个数所得到的数不是质数。

解题思路:

  先用素数筛找出 1 到 500000 的所有质数。

  在输入一个集合的时候,我们顺便记录下输入的这个数在输入数组中的位置,找出它的所有质因数,记录下质因数的总个数,用一个vector记录下所有 “不同的” 质因数。

  遍历输入数组中的每一个数,对于每个数,遍历其所有 “不同的” 质因数,如果找到这样的一个质因数:该数除以这个质因数能得到输入数组中的另一个数,那么将这两个数连边。

  将由上述的连边操作得到的图中的点分成两类:质因数总个数为奇数的点和质因数总个数为偶数的点(这个划分有点隐晦,我多说两句:其实,对于连边的两个数,二者各自的所有质因数其实就只有一个质数的差别,其中一个数的所有质因数中有这个质数,但另一个数没有,其他的质因数都相同;所以,他们质因数的总个数相差 1,故其中一个为奇数,一个为偶数),这样一来,这个图就变成一个二分图了。而答案其实就是求这个二分图的最大独立集。

  另:用匈牙利算法者,T!用 Hopcroft-Carp者方有可能AC。

AC代码:

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue> using namespace std;
const int inf=0x3f3f3f3f; bool prime[];
int have[],num[];
int prims[]; vector<int> G[];
int uN;
int l[];
int Mx[],My[];
int dx[],dy[];
int dis;
bool used[];
bool SearchP(){
queue<int>Q;
dis=inf;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i=;i<uN;i++){
if(Mx[l[i]]==-){
Q.push(l[i]);
dx[l[i]]=;
}
}
while(!Q.empty()){
int u=Q.front();
Q.pop();
if(dx[u]>dis) break;
int sz=G[u].size();
for(int i=;i<sz;i++){
int v=G[u][i];
if(dy[v]==-){
dy[v]=dx[u]+;
if(My[v]==-) dis=dy[v];
else{
dx[My[v]]=dy[v]+;
Q.push(My[v]);
}
}
}
}
return dis!=inf;
}
bool DFS(int u){
int sz=G[u].size();
for(int i=;i<sz;i++){
int v=G[u][i];
if(!used[v]&&dy[v]==dx[u]+){
used[v]=true;
if(My[v]!=-&&dy[v]==dis) continue;
if(My[v]==-||DFS(My[v])){
My[v]=u;
Mx[u]=v;
return true;
}
}
}
return false;
}
int MaxMatch(){
int res=;
memset(Mx,-,sizeof(Mx));
memset(My,-,sizeof(My));
while(SearchP()){
memset(used,false,sizeof(used));
for(int i=;i<uN;i++){
if(Mx[l[i]]==-&&DFS(l[i])) res++;
}
}
return res;
}
void init(){
memset(prime,true,sizeof(prime));
prime[]=prime[]=false;
int cnt=;
for(int i=;i<=;i++){
if(prime[i]){
prims[cnt++]=i;
for(int j=*i;j<=;j+=i)
prime[j]=false;
}
}
}
int zhis[];
vector<int> zhiyinshu[];
int main(){
init();
int T,N;
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&N);
memset(have,,sizeof(have));
memset(zhis,,sizeof(zhis));
for(int i=;i<=N;i++){
G[i].clear();
zhiyinshu[i].clear();
scanf("%d",&num[i]);
have[num[i]]=i;
int tmp=num[i];
for(int j=;;j++){
if(prime[tmp]){
zhiyinshu[i].push_back(tmp);
zhis[i]++;
break;
}
if(tmp%prims[j]==){
tmp/=prims[j];
zhiyinshu[i].push_back(prims[j]);
zhis[i]++;
while(tmp%prims[j]==){
tmp/=prims[j];
zhis[i]++;
}
}
if(tmp<prims[j]) break;
}
}
for(int i=;i<=N;i++){
for(int j=;j<zhiyinshu[i].size();j++){
if(have[num[i]/zhiyinshu[i][j]]){
int u=have[num[i]/zhiyinshu[i][j]];
G[i].push_back(u);
G[u].push_back(i);
}
}
} uN=;
for(int i=;i<=N;i++){
if(zhis[i]%==){
l[uN++]=i;
}
}
printf("Case %d: %d\n",t,N-MaxMatch());
}
return ;
}

Lightoj1356的更多相关文章

  1. Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)

    题意: 找出一个集合中的最大独立集,任意两数字之间不能是素数倍数的关系. 思路: 最大独立集,必然是二分图. 最大数字50w,考虑对每个数质因子分解,然后枚举所有除去一个质因子后的数是否存在,存在则建 ...

随机推荐

  1. Git初始化本地代码及提交到服务器

    2019独角兽企业重金招聘Python工程师标准>>> 1.先安装Git客户端 2.进入需要提交的文件夹目录 3.打开Git Bash,点击右键中的Git Bash 打开git命令窗 ...

  2. SAAS 何以“免费”实现盈利

    本文讲的是SAAS 何以"免费"实现盈利,[IT168 资讯]"天下没有免费的午餐",然而众多厂商却恰恰打出了免费这张王牌,且做出了不小的成绩,淘宝就凭借免费淘 ...

  3. Frame Relay Voice Traffic Shaping and Frament

    本文全称应该是:Frame Relay Voice-Adaptive Traffic Shaping and Fragmentation,标题限制字数,没办法了   帧中继的流量整型向来是个头疼的地方 ...

  4. Hardware Introduction

    计算机硬件组成可以概括为下图: CPU CPU生产商主要是Intel和AMD. Intel的产品主要有四种: Celeron(赛扬):低端处理器 Pentium(奔腾):比赛扬强,比酷睿弱 Xeon( ...

  5. python(面向对象-类封装调用)

    一.面对对象思想 (1)大家肯定听过 Python 中”一切皆对象“的说法,但可能并不了解它的具体含义,只是在学习的时候听说 Python 是面向对象的编程语言,本节将向大家详细介绍 Python 面 ...

  6. System.Linq.Dynamic字符串转委托

    以前一直想着有没有一个方法能够把字符串直接转化成函数的,刚好有需求就找了下,还真有. 微软地址:https://docs.microsoft.com/en-us/previous-versions/b ...

  7. docker 生产环境基础应用

    项目背景 此项目是在已有项目基础上,开发的一套相对独立的系统.项目总体分为三部分,前端.中间应用服务.流媒体服务.前端技术选型为vue+elementui,中间应用服务为.net core webap ...

  8. 化妆品行业的一个MES系统案例(三)

    项目的主要需求如下: (1) 管理产品的配方(物料BOM) (2) 管理产品的生产工艺(最终要将工艺参数下发到设备PLC自动执行) (3) 根据生产工单集合产品配方生成称量任务(其实领料之后的成料过程 ...

  9. spring学习笔记(六)自定义spring-boot-starter(2)

    上篇文章我们主要讲了spring自动装配的原理,我们知道了springboot在启动的时候会自动去读.factories文件,在factories文件中,autoConfiguration对应的就是我 ...

  10. 004_Python的列表切片,增删改查,常用操作方法,元组,range,join

    列表 列表是Python中的基础数据类型之一,它是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = ['kevin',123,True,(1,2,3,'wusir'), ...