题意:

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

思路:

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

最大数字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. powershell入门教程-v0.3版

    powershell入门教程-v0.3版 来源 https://www.itsvse.com/thread-3650-1-1.html 参考 http://www.cnblogs.com/piapia ...

  2. [Leetcode] unique paths 独特路径

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  3. POJ3415 Common Substrings 【后缀数组 + 单调栈】

    常见的子串 时间限制: 5000MS   内存限制: 65536K 提交总数: 11942   接受: 4051 描述 字符串T的子字符串被定义为: Ť(我,ķ)= Ť 我 Ť 我 1 ... Ť I ...

  4. 【POJ 3169 Layout】

    Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 12565Accepted: 6043 Description Like every ...

  5. dhcp 和ntpdate时间同步

    为了防止路由器的dhcp服务干扰实验,我们2台机器分别新加了1快网卡. vmnet4 dhcp安装 [root@ygy130 ~]# yum -y install dhcp 将配置文件放在/etc/d ...

  6. android OTA升级包制作

    0.签名 java -Xmx2048m -jar out/host/linux-x86/framework/signapk.jar -w build/target/product/security/t ...

  7. POJ2391:Ombrophobic Bovines(最大流+Floyd+二分)

    Ombrophobic Bovines Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 21660Accepted: 4658 题目 ...

  8. The 'brew link' step did not complete successfully

    在mac 上更新node时遇到了一系列的问题: 卸载node重新安装之后提示: The 'brew link' step did not complete successfully 其实这里已经给出了 ...

  9. POJ 1320 Street Numbers 解佩尔方程

    传送门 Street Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2529   Accepted: 140 ...

  10. 51Nod 1212无向图最小生成树

    prim #include<stdio.h> #include<string.h> #define inf 0x3f3f3f3f ][]; ],lowc[]; ],int n) ...