LightOj1356-Prime Independence
2017-08-02 15:32
716 查看
传送门:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1356
A set of integers is called prime independent if none of its member is a prime multiple of another member. An integer a is said to be a prime multiple of b if,
a = b x k (where k is a prime [1])
So, 6 is a prime multiple of 2, but 8 is not. And for example, {2, 8, 17} is prime independent but {2, 8, 16} or {3, 6} are not.
Now, given a set of distinct positive integers, calculate the largest prime independent subset.
Input
Input starts with an integer T (≤ 20), denoting the number of test cases.
Each case starts with an integer N (1 ≤ N ≤ 40000) denoting the size of the set. Next line contains N integers separated by a single space. Each of these N integers are distinct and between 1 and 500000 inclusive.
Output
For each case, print the case number and the size of the largest prime independent subset.
Sample Input
3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3
Sample Output
Case 1: 3
Case 2: 3
Case 3: 2
Hint
1. An integer is said to be a prime if it's divisible by exactly two distinct integers. First few prime numbers are 2, 3, 5, 7, 11, 13, ...
2. Dataset is huge, use faster I/O methods.
题目大意;
定义一个集合为prime independent,在这个集合中满足:a=p*b(p是素数),其中a和b不能同时在该集合中。在给定的一个序列中找出最大满足上述条件的集合。
题解:
可以这样想:在序列中如果满足a=p*b切a,b都存在的话就对a和b建一条边。这样的话就是求在这个序列中有多少互相独立的点。可以联想到最大独立集的问题。然而最大独立集是利用二分图求的(当然可以用网络流)。现在是怎么建一个二分图。可以看出在建a和b的边的时候a和b的关系。b的素因子个数等于a的素因子个数+1,也就是说只要连边的两个数的素因子个数的奇偶性就不同,那么现在按着每个数的素因子个数的奇偶划分出二分图,然后在求最大独立集=总个数-最大匹配。
求二分图的最大匹配问题的算法个人只会匈牙利算法O(nm)的时间复杂度。显然在这个题是行不通的。听说
Hopcroft-Karp算法
A set of integers is called prime independent if none of its member is a prime multiple of another member. An integer a is said to be a prime multiple of b if,
a = b x k (where k is a prime [1])
So, 6 is a prime multiple of 2, but 8 is not. And for example, {2, 8, 17} is prime independent but {2, 8, 16} or {3, 6} are not.
Now, given a set of distinct positive integers, calculate the largest prime independent subset.
Input
Input starts with an integer T (≤ 20), denoting the number of test cases.
Each case starts with an integer N (1 ≤ N ≤ 40000) denoting the size of the set. Next line contains N integers separated by a single space. Each of these N integers are distinct and between 1 and 500000 inclusive.
Output
For each case, print the case number and the size of the largest prime independent subset.
Sample Input
3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3
Sample Output
Case 1: 3
Case 2: 3
Case 3: 2
Hint
1. An integer is said to be a prime if it's divisible by exactly two distinct integers. First few prime numbers are 2, 3, 5, 7, 11, 13, ...
2. Dataset is huge, use faster I/O methods.
题目大意;
定义一个集合为prime independent,在这个集合中满足:a=p*b(p是素数),其中a和b不能同时在该集合中。在给定的一个序列中找出最大满足上述条件的集合。
题解:
可以这样想:在序列中如果满足a=p*b切a,b都存在的话就对a和b建一条边。这样的话就是求在这个序列中有多少互相独立的点。可以联想到最大独立集的问题。然而最大独立集是利用二分图求的(当然可以用网络流)。现在是怎么建一个二分图。可以看出在建a和b的边的时候a和b的关系。b的素因子个数等于a的素因子个数+1,也就是说只要连边的两个数的素因子个数的奇偶性就不同,那么现在按着每个数的素因子个数的奇偶划分出二分图,然后在求最大独立集=总个数-最大匹配。
求二分图的最大匹配问题的算法个人只会匈牙利算法O(nm)的时间复杂度。显然在这个题是行不通的。听说
Hopcroft-Karp算法
可以是O(nm^0.5)的时间。学习关于二分图的知识讲解可以点击:http://dsqiu.iteye.com/blog/1689505
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <cmath> #include <algorithm> #include <cstdlib> using namespace std; const int MAXN=550000; int mark[MAXN],odd[MAXN],A[MAXN],even[MAXN],used[MAXN]; struct node { int u,v; int nex; } eage[300000]; int head[60000],cnt,n,m; void init() { cnt=m=0; memset(head,-1,sizeof(head)); memset(mark,0,sizeof(mark)); memset(even,0,sizeof(even)); } void ADD(int u,int v) { eage[cnt].u=u; eage[cnt].v=v; eage[cnt].nex=head[u]; head[u]=cnt++; } const int INF = 1<<28; int um[MAXN],vm[MAXN]; int dx[MAXN],dy[MAXN],dis; bool vis[MAXN]; bool searchP() { queue<int>q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=1;i<=m;i++) if(um[odd[i]]==-1) { q.push(odd[i]); dx[odd[i]]=0; } while(!q.empty()) { int u=q.front();q.pop(); if(dx[u]>dis) break; for(int i=head[u];i!=-1;i=eage[i].nex) { int v =eage[i].v; if(dy[v]==-1) { dy[v]=dx[u]+1; if(vm[v]==-1) dis=dy[v]; else { dx[vm[v]]=dy[v]+1; q.push(vm[v]); } } } } return dis!=INF; } bool dfs(int u) { for(int i=head[u];i!=-1;i=eage[i].nex) { int v = eage[i].v; if(!vis[v]&&dy[v]==dx[u]+1) { vis[v]=1; if(vm[v]!=-1&&dy[v]==dis) continue; if(vm[v]==-1||dfs(vm[v])) { vm[v]=u;um[u]=v; return 1; } } } return 0; } int maxMatch() { int res=0; memset(um,-1,sizeof(um)); memset(vm,-1,sizeof(vm)); while(searchP()) { memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++) if(um[odd[i]]==-1&&dfs(odd[i])) res++; } return res; } void work() { init(); scanf("%d",&n); for(int i=1; i<=n; i++)scanf("%d",&A[i]),mark[A[i]]=i; for(int i=1; i<=n; i++) { int temp=A[i],num=0; for(int j=2; j<=sqrt(temp+0.5); j++) { if(temp%j==0) { int k=A[i]/j; if(mark[k]) { ADD(i,mark[k]); ADD(mark[k],i); } while(temp%j==0) { num++; temp=temp/j; } } } if(temp>1) { int k=A[i]/temp; if(mark[k]) { ADD(i,mark[k]); ADD(mark[k],i); } num++; } if(num&1)odd[++m]=i; } cout<<n-maxMatch() <<endl; } int main() { int T,w=0; scanf("%d",&T); while(T--) { printf("Case %d: ",++w); work(); } return 0; }
相关文章推荐
- Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)
- LightOJ 1356 Prime Independence( Hopcroft–Karp Bipartite算法)
- LightOJ 1356 Prime Independence 二分图最大独立集,HK算法
- Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)
- Lightoj-1356 Prime Independence(质因子分解&&二分图最大独立集)
- LightOJ 1356 Prime Independence (素数+二分图)
- lightoj 1356 - Prime Independence 【质因子分解 奇偶构图 + HK优化】
- LightOJ 1356 Prime Independence
- LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)
- LightOJ 1356 Prime Independence(素数筛选法+最大独立集)(Hopcroft-Carp算法)
- LightOJ 1356 Aladdin and the Flying Carpet(唯一分解定理)
- Prime Independence(质因子分解+二分图最大独立集)
- 基础数学 1002 LightOJ 1356
- LightOJ-1356-二分图匹配Hopcroft-Carp+数论
- [数论] HOJ 1356 Prime Judge Miller Rabin+快速幂
- LightOJ1029->Prime
- LightOJ - 1356
- LightOJ - 1356 质因数分解+最大独立子集
- HGC 1356 Prime Node【树形DP+线性素数打表】
- LightOJ 1356 && LightOJ 1336