题意:

找出一个集合中的最大独立集,任意两数字之间不能是素数倍数的关系。

思路:

最大独立集,必然是二分图。

最大数字50w,考虑对每个数质因子分解,然后枚举所有除去一个质因子后的数是否存在,存在则建边,考虑到能这样建边的数一定是质因子个数奇偶不同,所以相当于按奇偶区分建立了二分图,然后求二分图最大匹配,得到最大独立集就行了。

有一点这个题数据比较大,直接匈牙利炸了,要Hopcroft-Karp优化才能过。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
using namespace std;
typedef long long ll;
const int N = 5e4+;
int n,m,sum,res,flag;
bool mark[*N];
int pri[N],cnt;
void SP()
{
cnt=;
memset(mark,true,sizeof(mark));
mark[]=mark[]=false;
for(int i=; i<*N; i++)
{
if(mark[i])
pri[cnt++]=i;
for (int j=; (j<cnt)&&(i*pri[j]<*N); j++)
{
mark[i*pri[j]]=false;
if (i%pri[j]==)
break;
}
}
}
int pos[*N],num[N];
int f[N];
int vm[N],um[N];
bool vis[N];
vector<int>g[N];
int dx[N],dy[N],dis;
void init()
{
n=m=;
memset(pos,,sizeof(pos));
memset(f,-,sizeof(f));
memset(vm,-,sizeof(vm));
memset(um,-,sizeof(um));
for(int i=; i<=sum; i++)
g[i].clear();
}
void inserts(int u, int v)
{
g[u].push_back(v);
}
bool searchP()
{
queue<int>q;
dis=inf;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i=; i<=sum; i++)
if(um[i]==-)
{
q.push(i);
dx[i]=;
}
while(!q.empty())
{
int u=q.front();
q.pop();
if(dx[u]>dis) break;
for(int i=; i<g[u].size(); i++)
{
int v = g[u][i];
if(dy[v]==-)
{
dy[v]=dx[u]+;
if(vm[v]==-) dis=dy[v];
else
{
dx[vm[v]]=dy[v]+;
q.push(vm[v]);
}
}
}
}
return dis!=inf;
}
bool dfs(int u)
{
for(int i=; i<g[u].size(); i++)
{
int v = g[u][i];
if(!vis[v]&&dy[v]==dx[u]+)
{
vis[v]=;
if(vm[v]!=-&&dy[v]==dis) continue;
if(vm[v]==-||dfs(vm[v]))
{
vm[v]=u;
um[u]=v;
return ;
}
}
}
return ;
}
int maxMatch()
{
int res=;
while(searchP())
{
memset(vis,,sizeof(vis));
for(int i=; i<=sum; i++)
if(um[i]==-&&dfs(i)) res++;
}
return res;
}
int tmp[N],now,all;
void solve(int t,int tot)
{
now = all = ;
int tt=t;
for(int i=; i<cnt&&pri[i]*pri[i]<=tt; i++)
{
if(tt%pri[i]==)
tmp[now++] = pri[i];
while(tt%pri[i]==)
tt/=pri[i],all++;
}
if(tt>)tmp[now++] = tt, all++;
f[tot]=&all;
if(f[tot])n++;
else m++;
for(int i=; i<now; i++)
{
int x=t/tmp[i];
if(pos[x])
{
if(!f[tot])inserts(tot,pos[x]);
else inserts(pos[x],tot);
}
}
}
int main()
{
int i,j,k,cas,T,t,x,y,z;
SP();
scanf("%d",&T);
cas=;
while(T--)
{
scanf("%d",&sum);
init();
for(i=; i<=sum; i++)
scanf("%d",&num[i]);
for(i=; i<=sum; i++)
pos[num[i]] = i;
for(i=; i<=sum; i++)
solve(num[i],i);
printf("Case %d: %d\n",++cas,sum-maxMatch());
}
return ;
}

Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)的更多相关文章

  1. LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)

    http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1356 题意: 给出n个数,问最多能选几个数,使得该集合中的 ...

  2. LightOJ - 1356 Prime Independence (数论+二分图匹配)

    题意:有N个数的集合,其中选出若干个数组成一个子集,要求这个子集中的任意两个数a,b都不能通过a=k*b得到,其中k是一个素数.求这个子集最大的size. 分析:集合中任意两数的关系是二者之间是否之差 ...

  3. LightOJ 1356 Prime Independence 二分图最大独立集,HK算法

    这个题唯一需要说的就是普通的匈牙利算法是O(nm)的,过不了 然后HK算法可以O(n^0.5m),这个算法可以每次找很多同样长度的最短增广路 分析见:http://www.hardbird.net/l ...

  4. LightOJ - 1356 Prime Independence (二分图 最大独立集 素数打表)

    题意: 给你一个集合,让你从这个集合中挑选出几个数,使得这几个数中任意两个数相除后的值不能为素数 即挑选出来的这几个数不能互相冲突 最大独立集 = 所有点数 - 最大匹配数 呵..呵...原先用的二维 ...

  5. P2043 质因子分解

    P2043 质因子分解 题目描述 对N!进行质因子分解. 输入输出格式 输入格式: 输入数据仅有一行包含一个正整数N,N<=10000. 输出格式: 输出数据包含若干行,每行两个正整数p,a,中 ...

  6. P2043 质因子分解(阶乘的质因数分解)

    P2043 质因子分解 对$n!$进行质因数分解的一种高效算法 首先,筛出$<=n$的素数 蓝后,对$n$反复除以$prime$,同时$cnt+=n/prime$ $n!$中含有该$prime$ ...

  7. LightOJ1336 Sigma Function —— 质因子分解、约数和为偶数

    题目链接:https://vjudge.net/problem/LightOJ-1336 1336 - Sigma Function    PDF (English) Statistics Forum ...

  8. hdu2389二分图之Hopcroft Karp算法

    You're giving a party in the garden of your villa by the sea. The party is a huge success, and every ...

  9. BZOJ 1485: [HNOI2009]有趣的数列 [Catalan数 质因子分解]

    1485: [HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所 ...

随机推荐

  1. 【题解】[WC2006]水管局长

    感觉这题好强啊……本来以为能过,结果毫无疑问的被ge了一顿……在这里记录一下做的过程,也免得以后又忘记啦. 首先,我们应看出在这张图上,要让经过的水管最长的最短,就是要维护一棵动态的最小生成树.只是删 ...

  2. 部分经典IT书籍

    部分经典IT书籍 [系统,网路管理]1) Learning the Unix Operating System 1565923901 O'reilly/1997-4ed ***强力推荐给想入门unix ...

  3. [学习笔记]扩展LUCAS定理

    可以先做这个题[SDOI2010]古代猪文 此算法和LUCAS定理没有半毛钱关系. [模板]扩展卢卡斯 不保证P是质数. $C_n^m=\frac{n!}{m!(n-m)!}$ 麻烦的是分母. 如果互 ...

  4. sqlplus 几个命令:

    sqlplus 几个命令: 在sys,system,sysman,scott四个用户权限中,scott用户最低. 其权限依次从高到低. cmd进入sqlplus sqlplus 登录命令: 登录sys ...

  5. HDU2389:Rain on your Parade(二分图最大匹配+HK算法)

    Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Ot ...

  6. Centos7下redis设置密码、开放远程访问权限

    redis的安装与启动可参考前一篇文章:http://www.cnblogs.com/zuidongfeng/p/8032505.html redis安装成功后,默认是没有设置密码的启动redis-c ...

  7. Lesson 3

    1.关于面向对象的三个重要属性  Encapsulation(封装):无法直接访问类的成员变量,而是通过一些get set方法,间接访问数据域: Polymorphism(多态):静态绑定,动态绑定, ...

  8. java三

    1,深复制与浅复制 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. 深复制:被复制对象 ...

  9. 【Codeforces】849D. Rooter's Song

    [算法]模拟 [题意]http://codeforces.com/contest/849/problem/D 给定n个点从x轴或y轴的位置p时间t出发,相遇后按对方路径走,问每个数字撞到墙的位置.(还 ...

  10. .NET中zip的压缩和解压

    在.NET可以通过多种方式实现zip的压缩和解压:1.使用System.IO.Packaging:2.使用第三方类库:3.通过 System.IO.Compression 命名空间中新增的ZipArc ...