zoukankan      html  css  js  c++  java
  • LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)

    http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1356

    题意:

    给出n个数,问最多能选几个数,使得该集合中的任意两个数中其中一个数不是另一个质数倍。

    思路:

    二分图的最大独立集。

    那么怎么建图呢?
    我们按照质因数的奇偶性来分成两部分建图,如果两个数是质数倍的关系,那么就连边,最后最大独立集=点数-最大匹配。

    对每个数进行质因数分解,存储每个质因数和质因数的总数,比如说P,质因数为x1,x2,x3...接下来我们去看是否存在P/x1,P/x2...是否存在。如果存在的话,首先还要判断一下他们的质因数奇偶性,因为质数倍的数只有一个质因数不同,所以肯定是一奇一偶。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<queue>
      7 #include<cmath>
      8 #include<map>
      9 #include<stack>
     10 using namespace std;
     11 
     12 const int maxn=500000+5;
     13 const int INF=0x3f3f3f3f;
     14 
     15 int n;
     16 int cnt=0;
     17 int primes[maxn];
     18 int vis[maxn];
     19 
     20 vector<int>g[40005];
     21 int um[maxn],vm[maxn];
     22 int dx[maxn],dy[maxn],dis;
     23 
     24 void get_primes()
     25 {
     26     int m=sqrt(maxn+0.5);
     27     for(int i=2;i<=m;i++)
     28     {
     29         if(!vis[i])
     30         {
     31             for(int j=i*i;j<=maxn;j+=i)
     32                 vis[j]=1;
     33         }
     34     }
     35     for(int i=2;i<=maxn;i++)
     36         if(!vis[i])   primes[cnt++]=i;
     37 }
     38 
     39 bool searchP()
     40 {
     41     queue<int>q;
     42     dis=INF;
     43     memset(dx,-1,sizeof(dx));
     44     memset(dy,-1,sizeof(dy));
     45     for(int i=1;i<=n;i++)
     46         if(um[i]==-1)
     47         {
     48             q.push(i);
     49             dx[i]=0;
     50         }
     51     while(!q.empty())
     52     {
     53         int u=q.front();q.pop();
     54         if(dx[u]>dis)  break;
     55         for(int i=0;i<g[u].size();i++)
     56         {
     57             int v = g[u][i];
     58             if(dy[v]==-1)
     59             {
     60                 dy[v]=dx[u]+1;
     61                 if(vm[v]==-1)  dis=dy[v];
     62                 else
     63                 {
     64                     dx[vm[v]]=dy[v]+1;
     65                     q.push(vm[v]);
     66                 }
     67             }
     68         }
     69     }
     70     return dis!=INF;
     71 }
     72 
     73 bool dfs(int u)
     74 {
     75     for(int i=0;i<g[u].size();i++)
     76     {
     77         int v = g[u][i];
     78         if(!vis[v]&&dy[v]==dx[u]+1)
     79         {
     80             vis[v]=1;
     81             if(vm[v]!=-1&&dy[v]==dis) continue;
     82             if(vm[v]==-1||dfs(vm[v]))
     83             {
     84                 vm[v]=u;um[u]=v;
     85                 return 1;
     86             }
     87         }
     88     }
     89     return 0;
     90 }
     91 
     92 int maxMatch()
     93 {
     94     int res=0;
     95     memset(um,-1,sizeof(um));
     96     memset(vm,-1,sizeof(vm));
     97     while(searchP())
     98     {
     99         memset(vis,0,sizeof(vis));
    100         for(int i=1;i<=n;i++)
    101           if(um[i]==-1&&dfs(i))  res++;
    102     }
    103     return res;
    104 }
    105 
    106 int a[maxn],b[maxn],p[maxn],num[maxn];
    107 
    108 int main()
    109 {
    110     //freopen("D:\input.txt","r",stdin);
    111     int T;
    112     int kase=0;
    113     get_primes();
    114     scanf("%d",&T);
    115     while(T--)
    116     {
    117         scanf("%d",&n);
    118         for(int i=0;i<=n;i++)   g[i].clear();
    119         memset(b,-1,sizeof(b));
    120         for(int i=1;i<=n;i++)
    121             scanf("%d",&a[i]);
    122         sort(a+1,a+1+n);
    123         for(int i=1;i<=n;i++)
    124             b[a[i]]=i;
    125 
    126         memset(num,0,sizeof(num));
    127         for(int i=1;i<=n;i++)
    128         {
    129             int x=a[i];
    130             int sum1=0;
    131             int sum2=0;
    132             for(int j=0;primes[j]*primes[j]<=x;j++)
    133             {
    134                 if(x%primes[j]==0)
    135                 {
    136                     p[sum1++]=primes[j];
    137                     while(x%primes[j]==0)   {x/=primes[j];sum2++;}
    138                 }
    139             }
    140             if(x>1)  {p[sum1++]=x;sum2++;}
    141             num[i]=sum2;
    142             for(int j=0;j<sum1;j++)
    143             {
    144                 int t=b[a[i]/p[j]];
    145                 if(t<i&&t>0)
    146                 {
    147                     if((sum2&1)==(num[t]&1))  continue;
    148                     if(sum2&1)  g[i].push_back(t);
    149                     else  g[t].push_back(i);
    150                 }
    151             }
    152         }
    153 
    154         printf("Case %d: %d
    ",++kase,n-maxMatch());
    155     }
    156 
    157     return 0;
    158 }
  • 相关阅读:
    centos7 mysql 数据库备份与还原
    Centos 7 搭建wordpress
    Centos 7 安装 mysql5.7
    linux 搭建php网站许愿墙
    GNOME桌面的安装
    cetnos 7 ntp服务的安装与配置
    Tornado初探
    Mysql报错 Cannot load from mysql.proc
    zabbix install
    PYPY_GC
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6819684.html
Copyright © 2011-2022 走看看