Light oj 1356

版权声明:转载请注明出处,欢迎讨论,共同进步,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;
}

猜你喜欢

转载自blog.csdn.net/ACM2017/article/details/83142621