1. 程式人生 > >F - Prime Independence LightOJ1356

F - Prime Independence LightOJ1356

tinc lin urn con multipl acc cal math 分享

F - Prime Independence

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Others) Submit Status

Problem Description

A set of integers is called prime independent if none of its member is a prime multiple of another member. An integer a is said to be a prime multiple of b if,

a = b x k (where k is a prime [1])

So, 6 is a prime multiple of 2, but 8 is not. And for example, {2, 8, 17} is prime independent but {2, 8, 16} or {3, 6} are not.

Now, given a set of distinct positive integers, calculate the largest prime independent subset.

Input

Input starts with an integer T (≤ 20)

, denoting the number of test cases.

Each case starts with an integer N (1 ≤ N ≤ 40000) denoting the size of the set. Next line contains N integers separated by a single space. Each of these N integers are distinct and between 1 and 500000 inclusive.

Output

For each case, print the case number and the size of the largest prime independent subset.

Sample Input

3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3

Sample Output

Case 1: 3
Case 2: 3
Case 3: 2

Hint

An integer is said to be a prime if it‘s divisible by exactly two distinct integers. First few prime numbers are 2, 3, 5, 7, 11, 13, ...
Dataset is huge, use faster I/O methods.

技術分享
  1 #include <stdio.h>
  2 #include <queue>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <vector>
  7 #include <map>
  8 #include <set>
  9 #include <ctime>
 10 #include <cmath>
 11 #include <cctype>
 12 #include <iostream>
 13 using namespace std;
 14 typedef long long LL;
 15 const int N=5*1e5+10;
 16 const int INF=0x3f3f3f3f;
 17 const int maxn=40010;
 18 int cas=1,T;
 19 int id[N];
 20 struct maxMacth
 21 {
 22     int n;
 23     int vm[N],um[N];  
 24     bool vis[N];  
 25     vector<int>g[N];  
 26     int dx[N],dy[N],dis;  
 27     void init(int num)  
 28     {  
 29         n=num;
 30         memset(vm,-1,sizeof(vm));  
 31         memset(um,-1,sizeof(um));  
 32         for(int i=0;i<=n;i++)  
 33             g[i].clear();  
 34     }  
 35     void inserts(int u, int v)  
 36     {  
 37         g[u].push_back(v);  
 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     bool dfs(int u)  
 73     {  
 74         for(int i=0;i<g[u].size();i++)  
 75         {  
 76             int v = g[u][i];  
 77             if(!vis[v]&&dy[v]==dx[u]+1)  
 78             {  
 79                 vis[v]=1;  
 80                 if(vm[v]!=-1&&dy[v]==dis) continue;  
 81                 if(vm[v]==-1||dfs(vm[v]))  
 82                 {  
 83                     vm[v]=u;um[u]=v;  
 84                     return 1;  
 85                 }  
 86             }  
 87         }  
 88         return 0;  
 89     }  
 90     int maxMatch()  
 91     {  
 92         int res=0;  
 93         while(searchP())  
 94         {  
 95             memset(vis,0,sizeof(vis));  
 96             for(int i=1;i<=n;i++)  
 97               if(um[i]==-1&&dfs(i))  res++;  
 98         }  
 99         return res;  
100     }  
101 }MM;
102 int pn,p[N],vis[N],e[N];
103 void init()
104 {
105     memset(vis,0,sizeof(vis));
106     memset(e,0,sizeof(e));
107     pn=0;
108     for(int i=2;i<N;i++) if(!vis[i])
109     {
110         p[pn++]=i;
111         for(int j=i;j<N;j+=i)
112         {
113             vis[j]=1;
114             int x=j;
115             while(x%i==0) x/=i,e[j]++;
116         }
117     }
118 }
119 int main()
120 {
121 //    freopen("1.in","r",stdin);
122 //    freopen("1.out","w",stdout);
123     init();
124     scanf("%d",&T);
125     while(T--)
126     {
127         int n;
128         scanf("%d",&n);
129         memset(id,0,sizeof(id));
130         for(int i=1,x;i<=n;i++) scanf("%d",&x),id[x]=i;
131         MM.init(n);
132         for(int i=1;i<N;i++) if(id[i])
133         {
134             for(int j=0;i*p[j]<N && j<pn;j++) if(id[i*p[j]])
135             {
136                 if(e[i]&1) 
137                     MM.g[id[i]].push_back(id[i*p[j]]);
138                 else 
139                     MM.g[id[i*p[j]]].push_back(id[i]);
140             }
141         }
142         printf("Case %d: %d\n",cas++,n-MM.maxMatch());
143 //        printf("Case %d: %d\n",cas++,n-MM.maxMatch()/2);
144 //        cerr<<clock()<<"ms\n";
145     }
146     return 0;
147 }
solve.cpp

題解:

用篩法將滿足a×p=b(p為質數)的a,b建一條邊(註意方向),然後跑二分圖最大匹配,也可以直接建兩條邊,然後結果除以二
答案為:點數-最大匹配

F - Prime Independence LightOJ1356