首页 > 代码库 > LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)

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\n",++kase,n-maxMatch());155     }156 157     return 0;158 }

 

LightOJ 1356 Prime Independence(质因数分解+最大独立集+Hopcroft-Carp)