您的位置:首页 > 其它

LightOJ 1356 Prime Independence (素数+二分图)

2016-09-23 16:14 405 查看
B - Prime Independence

Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu

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

题解:

这道题的意思就是要你选出一个子集,其中任意两个数不能是素数倍数。

但是题目有一个条件,就是小于50万,所以输入的40000个数我们可以预处理。

由于题目是要求我们求最大的子集的大小,我们可以考虑把有素数倍数的建边,然后跑一个二分图最大匹配,然后n减去就是了。

开始预处理每个数的素数倍数的数字,然后无情MLE。

还有这道题为什么卡匈牙利!!

#include<bits/stdc++.h>
using namespace std;

const int maxn=4e4+5;
const int maxm=5e5+5;
const int Max=5e5;
const int INF=0x3f3f3f3f;

int A[maxn];
int used[maxm];

vector<int> vec[maxm];
vector<int> pri;
vector<int> G[maxn];

bool Judge(int now) {
if(now==1)return false;
int up=(int)sqrt(now*1.00);
for(int i=2; i<=up; ++i) {
if(now%i==0)return false;
}
return true;
}

int um[maxm],vm[maxm],n;
int dx[maxm],dy[maxm],dis;
bool vis[maxm];

bool searchP() {
queue<int> q;
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
unsigned short Head=0,Tail=0;
for(int i=1; i<=n; 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;
memset(um,-1,sizeof(um));
memset(vm,-1,sizeof(vm));
while(searchP()) {
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++)
if(um[i]==-1&&dfs(i))  res++;
}
return res;
}

int main() {
pri.clear();
for(int i=2; i<=Max; ++i) {
if(Judge(i)) {
pri.push_back(i);
}
}
int T,Tc=0;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
memset(used,0,sizeof(used));
for(int i=1; i<=n; ++i) {
scanf("%d",&A[i]);
used[A[i]]=i;
G[i].clear();
}
for(int i=1; i<=n; ++i) {
int len=(int)pri.size();
for(int j=0; j<len&&(long long)pri[j]*A[i]<=Max; ++j) {
int pos=used[pri[j]*A[i]];
if(pos) {
G[pos].push_back(i),G[i].push_back(pos);
}
}
}
printf("Case %d: %d\n",++Tc,n-maxMatch()/2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: