zoukankan      html  css  js  c++  java
  • Lightoj-1356 Prime Independence(质因子分解)(Hopcroft-Karp优化的最大匹配)

    题意:

    找出一个集合中的最大独立集,任意两数字之间不能是素数倍数的关系。

    思路:

    最大独立集,必然是二分图。

    最大数字50w,考虑对每个数质因子分解,然后枚举所有除去一个质因子后的数是否存在,存在则建边,考虑到能这样建边的数一定是质因子个数奇偶不同,所以相当于按奇偶区分建立了二分图,然后求二分图最大匹配,得到最大独立集就行了。

    有一点这个题数据比较大,直接匈牙利炸了,要Hopcroft-Karp优化才能过。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    using namespace std;
    typedef long long ll;
    const int  N = 5e4+10;
    int n,m,sum,res,flag;
    bool mark[10*N];
    int pri[N],cnt;
    void SP()
    {
        cnt=0;
        memset(mark,true,sizeof(mark));
        mark[0]=mark[1]=false;
        for(int i=2; i<10*N; i++)
        {
            if(mark[i])
                pri[cnt++]=i;
            for (int j=0; (j<cnt)&&(i*pri[j]<10*N); j++)
            {
                mark[i*pri[j]]=false;
                if (i%pri[j]==0)
                    break;
            }
        }
    }
    int pos[10*N],num[N];
    int f[N];
    int vm[N],um[N];
    bool vis[N];
    vector<int>g[N];
    int dx[N],dy[N],dis;
    void init()
    {
        n=m=0;
        memset(pos,0,sizeof(pos));
        memset(f,-1,sizeof(f));
        memset(vm,-1,sizeof(vm));
        memset(um,-1,sizeof(um));
        for(int i=0; i<=sum; i++)
            g[i].clear();
    }
    void inserts(int u, int v)
    {
        g[u].push_back(v);
    }
    bool searchP()
    {
        queue<int>q;
        dis=inf;
        memset(dx,-1,sizeof(dx));
        memset(dy,-1,sizeof(dy));
        for(int i=1; i<=sum; i++)
            if(um[i]==-1)
            {
                q.push(i);
                dx[i]=0;
            }
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            if(dx[u]>dis)  break;
            for(int i=0; i<g[u].size(); i++)
            {
                int v = g[u][i];
                if(dy[v]==-1)
                {
                    dy[v]=dx[u]+1;
                    if(vm[v]==-1)  dis=dy[v];
                    else
                    {
                        dx[vm[v]]=dy[v]+1;
                        q.push(vm[v]);
                    }
                }
            }
        }
        return dis!=inf;
    }
    bool dfs(int u)
    {
        for(int i=0; i<g[u].size(); i++)
        {
            int v = g[u][i];
            if(!vis[v]&&dy[v]==dx[u]+1)
            {
                vis[v]=1;
                if(vm[v]!=-1&&dy[v]==dis) continue;
                if(vm[v]==-1||dfs(vm[v]))
                {
                    vm[v]=u;
                    um[u]=v;
                    return 1;
                }
            }
        }
        return 0;
    }
    int maxMatch()
    {
        int res=0;
        while(searchP())
        {
            memset(vis,0,sizeof(vis));
            for(int i=1; i<=sum; i++)
                if(um[i]==-1&&dfs(i))  res++;
        }
        return res;
    }
    int tmp[N],now,all;
    void solve(int t,int tot)
    {
        now = all = 0;
        int tt=t;
        for(int i=0; i<cnt&&pri[i]*pri[i]<=tt; i++)
        {
            if(tt%pri[i]==0)
                tmp[now++] = pri[i];
            while(tt%pri[i]==0)
                tt/=pri[i],all++;
        }
        if(tt>1)tmp[now++] = tt, all++;
        f[tot]=1&all;
        if(f[tot])n++;
        else m++;
        for(int i=0; i<now; i++)
        {
            int x=t/tmp[i];
            if(pos[x])
            {
                if(!f[tot])inserts(tot,pos[x]);
                else inserts(pos[x],tot);
            }
        }
    }
    int main()
    {
        int i,j,k,cas,T,t,x,y,z;
        SP();
        scanf("%d",&T);
        cas=0;
        while(T--)
        {
            scanf("%d",&sum);
            init();
            for(i=1; i<=sum; i++)
                scanf("%d",&num[i]);
            for(i=1; i<=sum; i++)
                pos[num[i]] = i;
            for(i=1; i<=sum; i++)
                solve(num[i],i);
            printf("Case %d: %d
    ",++cas,sum-maxMatch());
        }
        return 0;
    }
  • 相关阅读:
    Mac sublime安装package controller
    git 指定从其他分支拉取commit
    一台电脑多个git使用 push 时候出现denied
    hibernate class cast exception from object to ...
    PostgreSQL数据类型
    spring 注入失败
    angularJS seed 安装
    PowerMockito(PowerMock用法)
    powermockito “mock public 方法内部 Private方法的问题”
    快速创建maven 工程:simple java工程,webapp
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6557157.html
Copyright © 2011-2022 走看看