題意:ios
給定一個長爲 n 的數組,以及 m 對下標 (a, b) 且知足 a + b 爲奇數,每次操做能夠將同一組的兩個數同時除以一個公約數數組
問最多能進行多少次操做ui
\[1≤n,m ≤100,1≤ai ≤10^9\]spa
根據奇偶性二分圖定理此題一定考二分圖code
貪心,每次除一個質數ci
質數之間是獨立的,能夠分開考慮每個質因子get
建圖:s -x中質因子p數量-> x -inf-> y -y中質因子p數量-> tstring
最大權匹配就是這個質因子能帶來的最多操做數it
注意質因子分解別寫錯了,最後判x>1io
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <vector> #include <set> #include <map> #define fir first #define sec second using namespace std; const int N = 105, inf = 1e9; int n, m, a[N]; pair<int, int> b[N]; map<int, int> li[N]; set<int> s; void fac(int p) { int x = a[p], sx = sqrt(x) + 1; //printf("fac %d\n", a[p]); for(int i=2; i<=sx; i++) if(x % i == 0) { //printf("iii %d\n", i); int cnt = 0; while(x%i == 0) cnt++, x/=i; //printf("x %d\n", x); //li[p].push_back(make_pair(i, cnt)); li[p][i] = cnt; s.insert(i); } if(x > 1) li[p][x] = 1, s.insert(x); } namespace mf { int s, t; struct edge {int v, ne, c, f;} e[1005]; int cnt=1, h[N]; void ins(int u, int v, int c) { //printf("ins %d %d %d\n", u, v, c); e[++cnt] = (edge) {v, h[u], c, 0}; h[u] = cnt; e[++cnt] = (edge) {u, h[v], 0, 0}; h[v] = cnt; } int cur[N], vis[N], d[N], head, tail, q[N]; bool bfs() { memset(vis, 0, sizeof(vis)); head = tail = 1; q[tail++] = s; d[s] = 0; vis[s] = 1; while(head != tail) { int u = q[head++]; for(int i=h[u]; i; i=e[i].ne) { int v = e[i].v; if(!vis[v] && e[i].c > e[i].f) { vis[v] = 1; d[v] = d[u] + 1; q[tail++] = v; if(v == t) return true; } } } return false; } int dfs(int u, int a) { if(u==t || a==0) return a; int flow = 0, f; for(int &i=cur[u]; i; i=e[i].ne) { int v = e[i].v; if(d[v] == d[u]+1 && (f = dfs(v, min(a, e[i].c-e[i].f))) > 0) { flow += f; e[i].f += f; e[i^1].f -= f; a -= f; if(a==0) break; } } if(a) d[u] = -1; return flow; } void build(int p) { cnt = 1; memset(h, 0, sizeof(h)); s=0; t=n+1; for(int i=1; i<=m; i++) ins(b[i].fir, b[i].sec, inf); for(int i=1; i<=n; i++) if(li[i].count(p)) { if(i & 1) ins(s, i, li[i][p]); else ins(i, t, li[i][p]); } } int solve(int p) { //printf("\nsolve %d\n", p); build(p); int flow = 0; while(bfs()) { for(int i=s; i<=t; i++) cur[i] = h[i]; flow += dfs(s, inf); } return flow; } } int main() { //freopen("in", "r", stdin); ios::sync_with_stdio(false); cin.tie(); cout.tie(); cin >> n >> m; for(int i=1; i<=n; i++) cin >> a[i]; for(int i=1; i<=m; i++) { cin >> b[i].fir >> b[i].sec; if(b[i].sec & 1) swap(b[i].fir, b[i].sec); } for(int i=1; i<=n; i++) fac(i); int ans = 0; for(set<int>::iterator it = s.begin(); it != s.end(); it++) ans += mf::solve(*it); cout << ans; }