题目链接: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. build.gradle 详解(一)

    简述: 1) Java 开发中有两个大名鼎鼎的项目构建 ANT.Maven. 2) Google 推荐使用的 Android studio 是采用 Gradle 来构建项目.Gradle 是一个非常先 ...

  2. Radix_Sort

    public class Radix_sort { public static void sort(int[] arrays,int radix){ int n = 1; int length = a ...

  3. 【阅读笔记】Ranking Relevance in Yahoo Search (三)—— query rewriting

    5. QUERY REWRITING 作用: query rewriting is the task of altering a given query so that it will get bet ...

  4. HDU Problem D [ Humble number ]——基础DP丑数序列

    Problem D Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  5. 轻量化模型:MobileNet v2

    MobileNet v2 论文链接:https://arxiv.org/abs/1801.04381 MobileNet v2是对MobileNet v1的改进,也是一个轻量化模型. 关于Mobile ...

  6. jmeter4.0,启动jmeter.bat闪退问题

    问题描述: 电脑重装win10系统,配置好了java环境后,解压jmeter的zip包,然后按照网上的教程配置环境变量,然后兴冲冲启动jmeter.bat,结果,闪退,甚至连个报错信息都没有... 然 ...

  7. IOS抓取与反抓取

    目录 IOS抓取基础知识 IOS抓取方式 iOS破解 模拟器 黑雷苹果模拟器 介绍 局限 改机软件 常用改机软件 检测 可更改属性 注入与Hook(越狱下实现作弊) 注入方式 Hook方式 重打包(非 ...

  8. 软件——Jira是什么

    JIRA这个工具接触有好几年了,在多个海外项目上都用过这个工具.去年又在项目上深度使用后就有点爱不释手了,回国后也在找机会推荐给其它项目上用.最近正好有新项目需要用,借这个机会把JIRA的配置学习的过 ...

  9. Java——类的访问修饰符

    1.java中外部类的访问修饰符有如下四种: public,默认,abstract,final // public,默认,abstract,final. public class Test1 {} c ...

  10. 牛客小白月赛16 小石的妹子 二分 or 线段树

    牛客小白月赛16 这个题目我AC之后看了一下别人的题解,基本上都是线段树,不过二分也可以. 这个题目很自然就肯定要对其中一个进行排序,排完序之后再处理另外一边,另一边记得离散化. 怎么处理呢,你仔细想 ...