1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <bits/stdc++.h> #define MAX_N 100000 #define MAX_M 5000000 #define INF 0x7f7f7f7f using namespace std; int tot = 46, pri[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199}; int n, m, s, t, cnt, x[MAX_N+5], y[MAX_N+5], z[MAX_N+5], pr[MAX_N+5], cr[MAX_N+5], d[MAX_N+5]; struct node {int v, c, nxt;} E[MAX_M+5]; vector <int> p[205]; void init() {s = 0, t = n+m+tot*tot*3+1, cnt = 0, memset(pr, -1, sizeof pr);} void insert(int u, int v, int c) {E[cnt] = (node){v, c, pr[u]}, pr[u] = cnt++;} void addedge(int u, int v, int c) {insert(u, v, c), insert(v, u, 0);} bool BFS() { queue <int> que; que.push(s); memset(d, -1, sizeof d), d[s] = 0; while (!que.empty()) { int u = que.front(); que.pop(); for (int i = pr[u]; ~i; i = E[i].nxt) { int v = E[i].v, c = E[i].c; if (!c || ~d[v]) continue; d[v] = d[u]+1, que.push(v); } } return ~d[t]; } int DFS(int u, int flow) { if (u == t) return flow; int ret = 0; for (int &i = pr[u]; ~i; i = E[i].nxt) { int v = E[i].v, c = E[i].c; if (!c || d[v] != d[u]+1) continue; int tmp = DFS(v, min(flow, c)); E[i].c -= tmp, E[i^1].c += tmp; flow -= tmp, ret += tmp; if (!flow) break; } if (!ret) d[u] = -1; return ret; } void cpy() {for (int i = s; i <= t; i++) cr[i] = pr[i];} void rec() {for (int i = s; i <= t; i++) pr[i] = cr[i];} int Dinic() {int ret = 0; cpy(); while (BFS()) ret += DFS(s, INF), rec(); return ret;} int trans(int i, int j) {return i*tot+j+1;} void build(int u) { int a = x[u], b = y[u], c = z[u]; for (int i = 0; i < (int)p[a].size(); i++) for (int j = 0; j < (int)p[b].size(); j++) if (u <= n) addedge(u, n+m+trans(p[a][i], p[b][j]), 1); else addedge(n+m+trans(p[a][i], p[b][j]), u, 1); for (int i = 0; i < (int)p[a].size(); i++) for (int j = 0; j < (int)p[c].size(); j++) if (u <= n) addedge(u, n+m+trans(p[a][i], p[c][j])+tot*tot, 1); else addedge(n+m+trans(p[a][i], p[c][j])+tot*tot, u, 1); for (int i = 0; i < (int)p[b].size(); i++) for (int j = 0; j < (int)p[c].size(); j++) if (u <= n) addedge(u, n+m+trans(p[b][i], p[c][j])+tot*tot*2, 1); else addedge(n+m+trans(p[b][i], p[c][j])+tot*tot*2, u, 1); } int main() { scanf("%d%d", &n, &m), init(); for (int i = 1; i <= 200; i++) for (int j = 0; j < tot; j++) if (i%pri[j] == 0) p[i].push_back(j); for (int i = 1; i <= n; i++) scanf("%d%d%d", x+i, y+i, z+i), addedge(s, i, 1), build(i); for (int i = n+1; i <= n+m; i++) scanf("%d%d%d", x+i, y+i, z+i), addedge(i, t, 1), build(i); return printf("%d", Dinic()), 0; }
|