1. 程式人生 > >Prime Independence

Prime Independence

scan close code tor 題意 prime con tmp ||

題意:

對於給定集合,求解最大的子集合,使得集合內兩兩之商不為質數。

解法:

考慮對於每一個數字分解質因數可以得到 $O(nloglogNUM)$ 條兩個數字不可以出現在同一集合的信息。

同時發現一條代表沖突的邊必然是聯結一個由奇數個質數連乘構成的數字和一個由偶數個質數連乘構成的數字。

是一個二分圖,考慮最大獨立集即可。

技術分享
#include <bits/stdc++.h>

const int N = 100010;

using namespace std;

int n,timnow;
int pre[N],a[N],v[N],cnt[N],Id[500010];
vector<int
> g[N],fac[N]; bool find(int x) { for(int i=0;i<(int)g[x].size();i++) { int p = g[x][i]; if(v[p] == timnow) continue; v[p] = timnow; if(!pre[p] || find(pre[p])) { pre[p] = x; return 1; } } return 0; } int main() {
int T,Te = 0; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) g[i].clear(),pre[i] = 0,fac[i].clear(),cnt[i]=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); Id[a[i]] = i; int tmp = a[i];
for(int j=2;j*j<=a[i];j++) if(tmp%j==0) { fac[i].push_back(j); while(tmp%j==0) tmp/=j, cnt[i]++; } if(tmp>1) fac[i].push_back(tmp), cnt[i]++; } for(int i=1;i<=n;i++) { for(int j=0;j<(int)fac[i].size();j++) { int tmp = a[i]/fac[i][j]; if(Id[tmp]) { int k = Id[tmp]; if(cnt[i]&1) g[i].push_back(k); else g[k].push_back(i); } } } int ans = 0; for(int i=1;i<=n;i++) { timnow ++; if(find(i)) ans++; Id[a[i]] = 0; } printf("Case %d: %d\n", ++Te, n-ans); } return 0; }
View Code

Prime Independence