版权声明:转载请注明出处,欢迎讨论,共同进步,QQ:1051780721 https://blog.csdn.net/ACM2017/article/details/83142621
二分图最大独立集+质因子分解
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f;
using namespace std;
const int MXN = 40010;
const int MXM = 200010;
const int MXX = 500010;
struct Edge{
int v,nxt;
}edge[MXM];
int head[MXN],edgeNum;
int a[MXN],id[MXN],num[MXX],vis[MXX];
int I,T,n,p[32],tot,x,y;
int dx[MXN],dy[MXN];//degree;
int mx[MXN],my[MXN];//match;
bool used[MXN];
void addEdge(int u,int v) {
edge[edgeNum]=(Edge){v,head[u]};
head[u]=edgeNum++;
}
void getPrime() {
int x;
for (int i=2;i<=500000;++i) {
x=i;
for (int j=2;j*j<=i;++j) {
if (x%j==0) {
while (x%j==0) {
x/=j;
num[i]++;
}
}
if (x==1) break;
}
if (x!=1) num[i]++;
}
// num[i]>1: i is a composite number;
// num[i]==1: i is a prime number;
// num[i]==0: i==1
}
void getN(int n) {
tot=0;
for (int i=2;i*i<=n;++i) {
if (n%i==0) {
p[tot++]=i;
while (n%i==0) {
n/=i;
}
}
}
if (n!=1) p[tot++]=n;
}
void init() {
memset(head,-1,sizeof(head));
edgeNum=0;
}
void getMap() {
memset(vis,-1,sizeof(vis));
x=y=0;
scanf("%d",&n);
for (int i=0;i<n;++i) {
scanf("%d",&a[i]);
vis[a[i]]=i;
if (num[a[i]]&1) id[i]=++x;
else id[i]=++y;
}
init();
int b;
for (int i=0;i<n;++i) {
getN(a[i]);
for (int j=0;j<tot;++j) {
b = a[i]/p[j];
if (~vis[b]) {
if (num[a[i]]%2!=0 && num[b]%2==0) addEdge(id[i],id[vis[b]]);
else if (num[a[i]]%2==0 && num[b]%2!=0) addEdge(id[vis[b]],id[i]);
}
}
}
}
int DFS(int u) {
int v;
for (int i=head[u];~i;i=edge[i].nxt) {
v=edge[i].v;
if (!used[v] && dy[v]==dx[u]+1) {
used[v]=true;
if (my[v]==-1||DFS(my[v])) {
my[v]=u;
mx[u]=v;
return 1;
}
}
}
return 0;
}
void HK() {
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
int ans=0,u,v,l,r;
int Q[MXN];
bool flag;
while(true) {
l=r=-1;
flag=false;
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
for (int i=1;i<=x;++i) if (mx[i]==-1) Q[++r]=i;
while (l<r) {
u=Q[++l];
for (int i=head[u];~i;i=edge[i].nxt) {
v=edge[i].v;
if (!dy[v]) {
dy[v]=dx[u]+1;
if (my[v]==-1) flag=true;
else {
dx[my[v]]=dx[u]+1;
Q[++r]=my[v];
}
}
}
}
if (!flag) break;
memset(used,0,sizeof(used));
for (int i=1;i<=x;++i)
if (mx[i]==-1) ans+=DFS(i);
}
printf("Case %d: %d\n", ++I, n - ans);
}
int main() {
getPrime();
scanf("%d",&T);
while (T--) {
getMap();
HK();
}
return 0;
}