[hihoCoder] #1158 : 质数相关

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数。一个集合S被称为质数相关,是指S中存在两个质数相关的数,否则称S为质数无关。如{2, 8, 17}质数无关,但{2, 8, 16}, {3, 6}质数相关。现在给定一个集合S,问S的所有质数无关子集中,最大的子集的大小。

输入

第一行为一个数T,为数据组数。之后每组数据包含两行。

第一行为N,为集合S的大小。第二行为N个整数,表示集合内的数。

输出

对于每组数据输出一行,形如"Case #X: Y"。X为数据编号,从1开始,Y为最大的子集的大小。

数据范围

1 ≤ T ≤ 20

集合S内的数两两不同且范围在1到500000之间。

小数据

1 ≤ N ≤ 15

大数据

1 ≤ N ≤ 1000

样例输入
3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3
样例输出
Case #1: 3
Case #2: 3
Case #3: 2

编程之美2015初赛第一场第三题,找二分图的最大独立集,大小为:点的个数 - 最大匹配。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int T, N;
 5 vector<int> v;
 6 vector<vector<int>> graph;
 7 vector<int> link;
 8 vector<bool> visited;
 9 bool *isPrime;
10 
11 void getPrime() {
12     isPrime = new bool[500001];
13     memset(isPrime, true, sizeof(bool) * 500001);
14     isPrime[0] = isPrime[1] = false;
15     for (int i = 2; i * i < 500001; ++i) if (isPrime[i]) {
16         for (int j = 2; i * j < 500001; ++j) isPrime[i * j] = false;
17     }
18 }
19 
20 int dfs(int u) {
21     for (auto v : graph[u]) if (!visited[v]) {
22         visited[v] = true;
23         if (link[v] == -1 || dfs(link[v])) {
24             link[v] = u;
25             return 1;
26         }
27     }
28     return 0;
29 }
30 
31 int hungary() {
32     int res = 0;
33     for (int i = 0; i < N; ++i) {
34         visited.assign(N + 1, false);
35         res += dfs(i);
36     }
37     return res / 2;
38 }
39 
40 int main() {
41     getPrime();
42     cin >> T;
43     for (int t = 1; t <= T; ++t) {
44         cin >> N;
45         v.resize(N);
46         for (int i = 0; i < N; ++i) {
47             cin >> v[i];
48         }
49         sort(v.begin(), v.end());
50         graph.assign(N + 1, vector<int>());
51         link.assign(N + 1, -1);
52         for (int i = 0; i < N - 1; ++i) {
53             for (int j = i + 1; j < N; ++j) {
54                 if (v[j] % v[i] == 0) {
55                     int tmp = v[j] / v[i];
56                     if (isPrime[tmp]) {
57                         graph[i].push_back(j);
58                         graph[j].push_back(i);
59                     }
60                 }
61             }
62         }
63         cout << "Case #" << t << ": ";
64         int res = hungary();
65         cout << N - res << endl;
66     }
67     return 0;
68 }
原文地址:https://www.cnblogs.com/easonliu/p/4463410.html