zoukankan      html  css  js  c++  java
  • 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());
        }
    }
  • 相关阅读:
    用U3D寻找看电视的感觉!!
    MipMap
    什么是 A 轮融资?有 B轮 C轮么?
    Java写的斗地主游戏源码
    sqlserver sp_spaceused用法
    SQL中的全局变量和局部变量(@@/@)
    SQL2008数据库导出到SQL2000全部步骤过程
    生成Insert语句的存储过程
    物理机连接虚拟机数据库
    配置sql server 2000以允许远程访问
  • 原文地址:https://www.cnblogs.com/smallhester/p/11260428.html
Copyright © 2011-2022 走看看