標籤:
題目3 : 質數相關時間限制:2000ms單點時限:1000ms記憶體限制:256MB描述
兩個數a和 b (a<b)被稱為質數相關,是指a × p = b,這裡p是一個質數。一個集合S被稱為質數相關,是指S中存在兩個質數相關的數,否則稱S為質數無關。如{2, 8, 17}質數無關,但{2, 8, 16}, {3, 6}質數相關。現在給定一個集合S,問S的所有質數無關子集中,最大的子集的大小。
輸入
第一行為一個數T,為資料群組數。之後每組資料包含兩行。
第一行為N,為集合S的大小。第二行為N個整數,表示集合內的數。
輸出
對於每組資料輸出一行,形如"Case #X: Y"。X為資料編號,從1開始,Y為最大的子集的大小。
資料範圍
1 ≤ T ≤ 20
集合S內的數兩兩不同且範圍在1到500000之間。
小資料
1 ≤ N ≤ 15
大資料
1 ≤ N ≤ 1000
-
範例輸入
-
352 4 8 16 3252 3 4 6 931 2 3
-
範例輸出
-
Case #1: 3Case #2: 3Case #3: 2
好像是LOJ的原題,- -
二分匹配求最大獨立集。
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;#define INF 0x3f3f3f3f#define ll long long#define N 1010#define M 500000int n,m,k;int a[N];int vis[N];int match[N];int mpt[N][N];int tot;bool isprime[M+10];int prime[M+10];void init(){ tot=0; memset(isprime,true,sizeof(isprime)); isprime[0]=isprime[1]=false; for(int i=2;i<=M;i++) { if(isprime[i]) prime[tot++]=i; for(int j=0;j<tot;j++) { if((ll)i*prime[j]>M) break; isprime[i*prime[j]]=false; if(i%prime[j]==0) break; } }}int dfs(int u){ for(int j=1;j<=n;j++) { if(!vis[j] && mpt[u][j]) { vis[j]=1; if(match[j]==-1 || dfs(match[j])) { match[j]=u; return 1; } } } return 0;}bool judge(int a,int b){ if(a>b) swap(a,b); if(b%a) return 0; int k=b/a; if(isprime[k]) return 1; return 0;}int main(){ init(); int T,iCase=1; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(mpt,0,sizeof(mpt)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(judge(a[i],a[j])) { mpt[i][j]=1; mpt[j][i]=1; } } } printf("Case #%d: ",iCase++); int ans=0; memset(match,-1,sizeof(match)); for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",n-ans/2); } return 0;}
[2015編程之美] 第一場C