Prime Independence LightOJ

题意:给你一组数,求一个最大的子集,要求任意两个的倍数都不是素数倍

题解:将每一个数按照质因数奇偶分开,同为奇偶的肯定是合数倍,在奇偶中刚好是素数倍的建边,跑二分图最大独立集,n - 匹配数就是答案

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define eps 1e-10
const int MAXN = 4e4 + 10;
const int MOD = 1e9+7;
const int MAXX = 500005;
int prime[MAXX];
int num[MAXN],pos[MAXX];
int n;

void getprime(){
    memset(prime,0,sizeof prime);
    for(int i = 2; i <= MAXX; i++){
        if(!prime[i]) prime[++prime[0]] = i;
        for(int j = 1 ;j <= prime[0] && prime[j] <= MAXX / i; j++){
            prime[prime[j] * i] = 1;
            if(i % prime[j] == 0) break;
        }
    }
}

vector<int>G[MAXN];
int uN;
int Mx[MAXN],My[MAXN];
int dx[MAXN],dy[MAXN];
int dis;
bool used[MAXN];
void addedge(int u,int v) {
    G[u].push_back(v);
}

bool SearchP(){
    queue<int>que;
    dis = INF;
    memset(dx,-1,sizeof dx);
    memset(dy,-1,sizeof dy);
    for(int i = 1; i <= uN; i++){
        if(Mx[i] == -1){
            que.push(i);
            dx[i] = 0;
        }
    }
    while(!que.empty()){
        int u = que.front();
        que.pop();
        if(dx[u] > dis) break;
        int sz = G[u].size();
        for(int i = 0; i < sz; i++) {
            int v = G[u][i];
            if(dy[v] == -1) {
                dy[v] = dx[u] + 1;
                if(My[v] == -1) dis = dy[v];
                else {
                    dx[My[v]] = dy[v] + 1;
                    que.push(My[v]);
                }
            }
        }
    }
    return dis != INF;
}

bool dfs(int u) {
    int sz = G[u].size();
    for (int i = 0; i < sz; i++) {
        int v = G[u][i];
        if(!used[v] && dy[v] == dx[u] + 1) {
            used[v] = true;
            if(My[v] != -1 && dy[v] == dis) continue;
            if(My[v] == -1 || dfs(My[v])) {
                My[v] = u;
                Mx[u] = v;
                return true;
            }
        }
    }
    return false;
}

int MaxMatch() {
    int res = 0;
    memset(Mx,-1,sizeof Mx);
    memset(My,-1,sizeof My);
    while(SearchP()) {
        memset(used,false,sizeof used);
        for (int i = 1; i <= uN; i++) {
            if(Mx[i] == -1 && dfs(i)) res++;
        }
    }
    return res;
}
int factor[105][2];
int fatcnt;
int sum;
int getFactors(int x) {
    fatcnt = 0;
    int tmp = x;
    for (int i = 1; prime[i] <= tmp / prime[i]; i++) {
        factor[fatcnt][1] = 0;
        if (tmp % prime[i] == 0) {
            factor[fatcnt][0] = prime[i];
            while (tmp % prime[i] == 0) {
                factor[fatcnt][1] ++;
                tmp /= prime[i];
                sum++;
            }
            fatcnt++;
        }
    }
    if(tmp != 1) {
        factor[fatcnt][0] = tmp;
        factor[fatcnt++][1] = 1;
        sum++;
    }
    return fatcnt;
}
void init() {
    uN = 0;
    memset(pos,0,sizeof pos);
    for(int i = 0;i <= n; i++)
        G[i].clear();
}

int main()
{
    getprime();
    int t;
    scanf("%d",&t);
    int ca = 1;
    while(t--) {
        init();
        scanf("%d", &n);
        uN = n;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &num[i]);
            pos[num[i]] = i;
        }
        for (int i = 1; i <= n; i++) {
           sum = 0;
           int pnum = getFactors(num[i]);
           for(int k = 0; k < pnum; k++) {
               if(pos[num[i] / factor[k][0]] != 0) {
                   if(sum & 1)
                        addedge(pos[num[i]],pos[num[i] / factor[k][0]]);
                   else
                       addedge(pos[num[i] / factor[k][0]], pos[num[i]]);
               }
           }
        }
        printf("Case %d: %d
",ca++,n - MaxMatch());
    }
}
原文地址:https://www.cnblogs.com/smallhester/p/11260428.html