LightOJ 1356 Prime Independence (Prime binary diagram)
Prime IndependenceTime Limit:3000 MSMemory Limit:32768KB64bit IO Format:% Lld & % llu Submit Status Practice LightOJ 1356
Description
A set of integers is called prime independent if none of its member is a prime multiple of another member. An integerAIs said to bePrime multipleOfBIf,
A = B x k(WhereKIs a prime [1])
So,6Is a prime multiple2,8Is not. And for example,{2, 8, 17}Is prime independent{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 integerT (≤ 20), Denoting the number of test cases.
Each case starts with an integerN (1 ≤ N ≤ 40000)Denoting the size of the set. Next line containsNIntegers separated by a single space. Each of theseNIntegers are distinct and1And500000Intrusive.
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
Question:
Returns n numbers to find an independent subset of the largest prime numbers. If a = B * is a prime number, a is considered to be a prime number multiplication level of B, if a set does not have a number that is the multiplication level of the prime number of another number, this is the independent subset of the prime number.
Ideas:
This is similar to the largest independent set, but this is an NP problem. I wonder if it can be converted into a bipartite graph.
In the idea of creating a graph, each number is either a multiplication level of an odd number or an even number, and there is no association between an odd number and an odd number. Based on this nature, the graph is divided into a bipartite graph, the rest is the bipartite graph algorithm. The time for this question is too tight. You must use an advanced bipartite graph algorithm.
Code:
# Include
# Include
# Include
# Define maxn 40005 using namespace std; int ans, n, m, num, cnt; bool app [500005]; int vis [500005], pri [50000], ha [500005]; int a [maxn], head [maxn]; int sta [maxn], top; bool use [maxn]; int nx, ny; int cx [maxn], cy [maxn]; // cx [I] indicates matching cy [I] corresponding to xi indicates matching int distx [maxn] corresponding to yi, disty [maxn]; // the nth layer in bfs int que [maxn * 20]; struct node {int v, next;} edge [maxn * 20]; void addedge (int u, int v) {cnt ++; edge [cnt]. v = v; edge [cnt]. next = head [u]; Head [u] = cnt;} void sieze () {int I, j; memset (app, 0, sizeof (app); for (I = 2; I <= 500000; I ++) {if (long) I * I> = 500000) break; if (! App [I]) for (j = I * I; j <= 500000; j + = I) {app [j] = 1 ;}} num = 0; for (I = 2; I <= 500000; I ++) {if (app [I] = 0) pri [++ num] = I;} memset (ha, 0, sizeof (ha); int res; for (I = 2; I <= 500000; I ++) {int x = I; res = 0; for (j = 1; j <= num & j * j <= x; j ++) {while (x % pri [j] = 0) {x/= pri [j]; res ++ ;}} if (x! = 1) res ++; ha [I] = res & 1;} // printf ("% d \ n", num);} void init () {memset (cx,-1, sizeof (cx); memset (cy,-1, sizeof (cy); memset (head,-1, sizeof (head);} bool bfs () {int I, j, k, u, v, h, t; bool flag = 0; memset (distx, 0, sizeof (distx); memset (disty, 0, sizeof (disty); t = 0; for (I = 1; I <= nx; I ++) {if (cx [I] =-1) que [t ++] = I ;}for (h = 0; h! = T; h ++) {u = que [h]; for (k = head [u]; k! =-1; k = edge [k]. next) {v = edge [k]. v; if (! Disty [v]) {disty [v] = distx [u] + 1; if (cy [v] =-1) flag = 1; else distx [cy [v] = disty [v] + 1, que [t ++] = cy [v] ;}} return flag ;} bool dfs (int I) {int j, k; for (k = head [I]; k! =-1; k = edge [k]. next) {j = edge [k]. v; if (disty [j] = distx [I] + 1) // indicates that j is the successor node of I {disty [j] = 0; // if (cy [j] =-1 | dfs (cy [j]) {cx [I] = j, cy [j] = I; return 1 ;}}return 0 ;}void Hopcroft_Karp () {int I, j; ans = 0; while (bfs () {for (I = 1; I <= nx; I ++) {if (cx [I] =-1 & dfs (I )) ans ++ ;}}void solve () {int I, j; int u, v; init (); cnt = 0; for (I = 1; I <= n; I ++) {for (j = 1; j <= num; j ++) {if (a [I] * pri [j]> 50 (0000) break; v = a [I] * pri [j]; if (vis [v]) {addedge (vis [a [I], vis [v]); addedge (vis [v], vis [a [I]) ;}} Hopcroft_Karp () ;}int main () {int I, j, t, ca = 0; sieze (); scanf ("% d", & t); while (t --) {scanf ("% d", & n); int tmp = 0; memset (vis, 0, sizeof (vis); for (I = 1; I <= n; I ++) {scanf ("% d ", & a [I]); if (ha [a [I]) vis [a [I] = + + tmp;} nx = tmp; ny = n-tmp; for (I = 1; I <= n; I ++) {if (! Ha [a [I]) vis [a [I] = + tmp;} solve (); printf ("Case % d: % d \ n ", ++ ca, n-ans);} return 0 ;}