Prime Independence LightOJ - 1356(二分圖匹配+最大獨立集)
阿新 • • 發佈:2018-11-17
題目連結:qaq
題意:給你一堆數,讓你找出最大一組數裡面不存在一個整數是另一個整數的素數倍,輸出最大數量。
思路:將數按質因子的數量奇偶分邊,然後將素數倍兩個整數=連邊。最後就是求最大獨立集的方法了
附上程式碼:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int MAXN = 500010; int prime[MAXN + 1]; int bn[40010]; int vis[MAXN]; int nnum[40010]; int ax[MAXN]; int sum = 0; const int N = 40100; const int inf = 0x3f3f3f3f; struct edge { int to, next; }g[N * 20]; int match[N], head[N]; bool used[N]; int nx, ny, cnt, dis; int dx[N], dy[N], cx[N], cy[N]; void add_edge(int v, int u) { g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++; } bool bfs() { queue<int>que; dis = inf; memset(dx, -1, sizeof(dx)); memset(dy, -1, sizeof(dy)); for (int i = 1; i <= nx; i++) { if (cx[i] == -1) { que.push(i); dx[i] = 0; } } while (!que.empty()) { int v = que.front(); que.pop(); if (dx[v]>dis) break; for (int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if (dy[u] == -1) { dy[u] = dx[v] + 1; if (cy[u] == -1) dis = dy[u]; else { dx[cy[u]] = dy[u] + 1; que.push(cy[u]); } } } } return dis != inf; } int dfs(int v) { for (int i = head[v]; i != -1; i = g[i].next) { int u = g[i].to; if (!used[u] && dy[u] == dx[v] + 1) { used[u] = true; if (cy[u] != -1 && dy[u] == dis) continue; if (cy[u] == -1 || dfs(cy[u])) { cy[u] = v; cx[v] = u; return 1; } } } return 0; } int hopcroft_karp() { int res = 0; memset(cx, -1, sizeof(cx)); memset(cy, -1, sizeof(cy)); while (bfs()) { memset(used, 0, sizeof(used)); for (int i = 1; i <= nx; i++) { if (cx[i] == -1) res += dfs(i); } } return res; } void getPrime() { memset(prime, 0, sizeof(prime)); for (int i = 2; i <= MAXN; i++) { if (!prime[i])prime[++prime[0]] = i; for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++) { prime[prime[j] * i] = 1; if (i%prime[j] == 0) break; } } } long long factor[100][2]; int fatCnt; int getFactors(long long x) { fatCnt = 0; long long tmp = x; for (int i = 1; prime[i] <= tmp / prime[i]; i++) { factor[fatCnt][1] = 0; if (tmp%prime[i] == 0) { factor[fatCnt][0] = prime[i]; while (tmp%prime[i] == 0) { factor[fatCnt][1]++; tmp /= prime[i]; sum++; } fatCnt++; } } if (tmp != 1) { factor[fatCnt][0] = tmp; factor[fatCnt++][1] = 1; sum++; } return fatCnt; } int main(void) { getPrime(); int t; scanf("%d", &t); int ca = 0; while (t--) { int n; cnt = 0; memset(ax, 0, sizeof(ax)); memset(vis, 0, sizeof(vis)); memset(head, -1, sizeof(head)); scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &bn[i]); ax[bn[i]] = 1; } nx = n; ny = 0; sort(bn + 1, bn + n + 1); for (int i = 1; i <= n; i++) { vis[bn[i]] = i; } for (int i = 1; i <= n; i++) { sum = 0; int num = getFactors(bn[i]); nnum[i] = num; for (int z = 0; z<num; z++) { if (ax[bn[i] / factor[z][0]]) { //printf("%d %d\n", vis[bn[i]], vis[bn[i] / factor[z][0]]); if (sum & 1) { add_edge(vis[bn[i]], vis[bn[i] / factor[z][0]]); } else { add_edge(vis[bn[i] / factor[z][0]], vis[bn[i]]); } //add_edge(vis[bn[i]],vis[bn[i]/factor[z][0]]); //add_edge(vis[bn[i]/factor[z][0]],vis[bn[i]]); } } } printf("Case %d: %d\n", ++ca, n - hopcroft_karp()); } return 0; }