## 4205: 卡牌配对 最大流+建图技巧

1 #include<cstdio>
2 #include<iostream>
3 #define rep(i,j,k) for(register int i = j; i <= k; i++)
4 #define ez(i,j) for(register int i = head[j]; i; i=e[i].next)
5 #define maxn 30005
6 #define maxm 70233
7 #define inf 0x7fffffff
8 using namespace std;
9
11     int s = 0, t = 1; char c = getchar();
12     while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
13     while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
14     return s * t;
15 }
16
17 struct edge{ int to, v, next; } e[maxm*500];
18 int head[maxm], S = 0, T, cnt = 1;
19 inline void add(int x,int y,int v) {
20     e[++cnt].to = y, e[cnt].v = v, e[cnt].next = head[x], head[x] = cnt;
21     e[++cnt].to = x, e[cnt].v = 0, e[cnt].next = head[y], head[y] = cnt;
22 }
23
24 int l, r, h[maxm], q[maxm];
25 #define to e[i].to
26 inline bool bfs() {
27     rep(i,1,T) h[i] = 0; h[S] = 1;
28     l = 0, r = 1; q[r] = S; int x;
29     while( l < r ) {
30         x = q[++l];
31         ez(i,x) if( !h[to] && e[i].v ) h[to] = h[x] + 1, q[++r] = to;
32     }
33     return h[T];
34 }
35
36 inline int dfs(int x,int f) {
37     if( x == T ) return f;
38     int used = 0, w;
39     ez(i,x) if( h[to] == h[x] + 1 && e[i].v ) {
40         w = dfs(to,min(e[i].v,f-used));
41         e[i].v -= w, e[i^1].v += w; used += w;
42         if( used == f ) return f;
43     }
44     if( !used ) h[x] = -1;
45     return used;
46 }
47
48 int A[maxn], B[maxn], C[maxn], n, m, ans = 0;
49 int pri[] = {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};
50 int bet[3][49][49], inl[maxn], inr[maxn], aq[maxn], bq[maxn], cq[maxn];
51
52 inline void flow() { while( bfs() ) ans += dfs(S,inf); }
53 int main() {
54     int n = read(), m = read(), l1, l2, l3, x, tot = 0;
55     rep(i,0,2) rep(j,0,48) rep(k,0,48) bet[i][j][k] = ++tot;
56     rep(i,1,n) inl[i] = ++tot; rep(i,1,m) inr[i] = ++tot;
57     S = 0, T = ++tot;
59     rep(k,1,n) {
61         l1 = 0, l2 = 0, l3 = 0;
62         x = A[k];
63         rep(i,0,48) if( x % pri[i] == 0 ) {
64                 aq[++l1] = i;
65                 while( x % pri[i] == 0 ) x /= pri[i];
66         } else if( x == 1 ) break;
67         x = B[k];
68         rep(i,0,48) if( x % pri[i] == 0 ) {
69                 bq[++l2] = i;
70                 while( x % pri[i] == 0 ) x /= pri[i];
71         } else if( x == 1 ) break;
72         x = C[k];
73         rep(i,0,48) if( x % pri[i] == 0 ) {
74                 cq[++l3] = i;
75                 while( x % pri[i] == 0 ) x /= pri[i];
76         } else if( x == 1 ) break;
80     }
82     rep(k,1,m) {
84         l1 = 0, l2 = 0, l3 = 0;
85         x = A[k];
86         rep(i,0,48) if( x % pri[i] == 0 ) {
87                 aq[++l1] = i;
88                 while( x % pri[i] == 0 ) x /= pri[i];
89         } else if( x == 1 ) break;
90         x = B[k];
91         rep(i,0,48) if( x % pri[i] == 0 ) {
92                 bq[++l2] = i;
93                 while( x % pri[i] == 0 ) x /= pri[i];
94         } else if( x == 1 ) break;
95         x = C[k];
96         rep(i,0,48) if( x % pri[i] == 0 ) {
97                 cq[++l3] = i;
98                 while( x % pri[i] == 0 ) x /= pri[i];
99         } else if( x == 1 ) break;