Prime Independence(质因子分解+二分图最大独立集)
来源:互联网 发布:以下哪种立体匹配算法 编辑:程序博客网 时间:2024/04/30 10:23
Description
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 multipleof 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
感觉超棒的一道题,值得一做。。。挺巧妙的。。。
找出一个集合中的最大独立集,任意两数字之间不能是素数倍数的关系。
思路:
最大独立集,必然是二分图。
最大数字50w,考虑对每个数质因子分解,然后枚举所有除去一个质因子后的数是否存在,存在则建边,考虑到能这样建边的数一定是质因子个数奇偶不同,所以相当于按奇偶区分建立了二分图,然后求二分图最大匹配,得到最大独立集就行了。
#pragma comment(linker, "/STACK:102400000,102400000"#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define MAX 100005#define INF 0x3f3f3f3f#define LL long long#define pii pair<int,int>#define rd(x) scanf("%d",&x)#define rd2(x,y) scanf("%d%d",&x,&y)///map<int,int>mmap;///map<int,int >::iterator it;using namespace std;#define N 500010#define M 40010int a[M],b[N],num[M],factor[1000];vector<int>mmap[M];int n;bool vis[M];int linker[M];bool dfs(int u){ for(int i=0;i<mmap[u].size();i++) { if(!vis[mmap[u][i]]) { vis[mmap[u][i]]=true; if(linker[ mmap[u][i] ]==-1||dfs(linker[ mmap[u][i] ])) { linker[mmap[u][i]]=u; return true; } } } return false;}int hungary(){ int u; int res=0; for(u=1;u<=n;u++) { memset(vis,false,sizeof(vis)); if(dfs(u)) res++; } return res;}void init(){ memset(num,0,sizeof(num)); memset(b,0,sizeof(b)); memset(linker,-1,sizeof(linker)); for(int i=1;i<=n;i++) mmap[i].clear();}int main(){ int T,Case,t; scanf("%d",&T); Case=1; while(T--) { scanf("%d",&n); init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) b[ a[i] ]=i; ///对节点哈希 for(int i=1;i<=n;i++) { t = a[i]; int cnt=0,sum=0; ///分解质因子 cnt质因子个数 sum为多少个质因子的积 for(int j=2;t>1&&j<=sqrt(t) ;j++) if(t%j==0) { factor[cnt++] = j; while(t%j==0) t/=j,sum++; } if(t>1) //t有可能是质数 factor[cnt++]=t,sum++; num[i] = sum; for(int j=0;j<cnt;j++) { t = b[ a[i] / factor[j] ]; if(t==0) ///都是奇数或者偶数 continue; if((sum&1)) ///是奇数 作为x部 mmap[i].push_back(t); else ///是偶数 mmap[t].push_back(i); } } printf("Case %d: %d\n",Case++,n-hungary()); } return 0;}
Hopcroft-Karp,数组有点乱。。。
#pragma comment(linker, "/STACK:102400000,102400000"#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define MAX 100005#define INF 0x3f3f3f3f#define LL long long#define pii pair<int,int>#define rd(x) scanf("%d",&x)#define rd2(x,y) scanf("%d%d",&x,&y)///map<int,int>mmap;///map<int,int >::iterator it;using namespace std;#define N 500010#define M 40010int a[N],b[N],num[N],factor[1000];vector<int>mmap[M];int um[N],vm[N],n;int dx[M],dy[M],dis;bool vis[M];bool searchP(){ queue<int>q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=1;i<=n;i++) if(um[i]==-1) { q.push(i); dx[i]=0; } while(!q.empty()) { int u=q.front();q.pop(); if(dx[u]>dis) break; for(int i=0;i<mmap[u].size();i++) { int v = mmap[u][i]; 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=0;i<mmap[u].size();i++) { int v = mmap[u][i]; 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<=n;i++) if(um[i]==-1&&dfs(i)) res++; } return res;}void init(){ memset(b,-1,sizeof(b)); memset(num,0,sizeof(num)); memset(vm,-1,sizeof(vm)); memset(um,-1,sizeof(um)); for(int i=0;i<=n;i++) mmap[i].clear();}int main(){ int k,kk,t,x,y,z; scanf("%d",&k); kk=0; while(k--) { scanf("%d",&n); init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) b[ a[i] ]=i; for(int i=1;i<=n;i++) { t = a[i]; int cnt=0,sum=0; ///分解质因子 cnt质因子个数 sum为多少个质因子的积 for(int j=2;t>1&&j<=sqrt(t) ;j++) if(t%j==0) { factor[cnt++] = j; while(t%j==0) t/=j,sum++; } if(t>1) //t有可能是质数 factor[cnt++]=t,sum++; num[i] = sum; for(int j=0;j<cnt;j++) { t = b[ a[i] / factor[j] ]; if( t==0 ) ///都是奇数或者偶数 continue; if((sum&1)) ///是奇数 作为x部 mmap[i].push_back(t); else ///是偶数 mmap[t].push_back(i); } } printf("Case %d: %d\n",++kk,n-maxMatch()); } return 0;}
- Prime Independence(质因子分解+二分图最大独立集)
- Lightoj-1356 Prime Independence(质因子分解&&二分图最大独立集)
- 【最大独立集】Prime Independence
- Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)
- Light OJ 1356 Prime Independence 最大独立集+素数筛选
- lightoj 1356 - Prime Independence 【质因子分解 奇偶构图 + HK优化】
- LightOJ 1356 Prime Independence(素数筛选法+最大独立集)(Hopcroft-Carp算法)
- LightOJ 1356 Prime Independence (素数 二分图)
- LightOJ 1356 Prime Independence (素数+二分图)
- 二分图最大独立集
- 二分图最大独立集
- 二分图最大独立集
- 二分图最大匹配 & 最大独立集
- poj 1365 Prime Land (质因子分解)
- hdu 3829 二分图最大独立集
- poj 2771 二分图最大独立集
- HDU2768二分图求最大独立集
- poj3692 Kindergarten 二分图最大独立集
- 去掉tabbar上方的黑线
- 设置导航栏的背景颜色
- 2016GDOI总结
- Appium Server 源码分析 (二) - main 方法
- zoj-3735 Josephina and RPG[概率dp]
- Prime Independence(质因子分解+二分图最大独立集)
- Gson学习
- 基于Servlet3.0 comet http长连接
- getopts命令行参数处理
- 两个多项式相乘 使用散列表加速 在计算时合并多项式的项
- Android内核开发:从源码树中删除出厂的app应用
- Bluemix使用与其他云平台对比
- Android最新flash播放器----iFlashPlayer被Adobe放弃的逆袭(softboy)
- Loadrunner开发tuxedo类型的脚本