题目中说每一个good pair<u,v> 都满足(u+v)%2 == 1,即一个奇数,一个偶数。
首先我们要拿出一原点S,汇点T,S联到所有的num[odd]的质因子上,T联到所有的num[even]的质因子上,边的流量为num[i]中相应质因子的个数。
再根据给出的<u,v>,假设u为奇数,则从u的质因子上联到相等的v的质因子上,流量为INF。
丢到模板里跑一遍就好了。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define INF 0x3f3f3f3f #define Mod 6000007 using namespace std; const int EDGE = 6000000,POINT = 4010; struct E { int u,v,Max,next; } edge[EDGE]; int head[POINT]; int curr[POINT]; int Top; void Link(int u,int v,int flow) { //printf("u = %d v = %d flow = %d\n",u,v,flow); edge[Top].u = u; edge[Top].v = v; edge[Top].Max = flow; edge[Top].next = head[u]; head[u] = Top++; } int dis[POINT],gap[POINT],pre[POINT]; queue<int> q; void Updata_Dis(int S,int T,int n) { memset(dis,-1,sizeof(dis)); memset(gap,0,sizeof(gap)); dis[T] = 0; gap[0] = 1; q.push(T); int f; while(q.empty() == false) { f = q.front(); q.pop(); for(int p = head[f]; p != -1; p = edge[p].next) { if(dis[edge[p].v] == -1) { dis[edge[p].v] = dis[f] + 1; gap[dis[f]+1]++; q.push(edge[p].v); } } } } int ISAP(int S,int T,int n) { memcpy(curr,head,sizeof(curr)); Updata_Dis(S,T,n); int flow = 0,u = pre[S] = S,p; while(dis[S] < n) { if(u == T) { int temp = INF,pos; for(p = S; p != T; p = edge[curr[p]].v) { if(temp > edge[curr[p]].Max) { temp = edge[curr[p]].Max; pos = p; } } for(p = S; p != T; p = edge[curr[p]].v) { edge[curr[p]].Max -= temp; edge[curr[p]^1].Max += temp; } flow += temp; u = pos; } for(p = curr[u]; p != -1; p = edge[p].next) { if(dis[edge[p].v]+1 == dis[u] && edge[p].Max) break; } if(p != -1) { curr[u] = p; pre[edge[p].v] = u; u = edge[p].v; } else { if((--gap[dis[u]]) == 0) break; int temp = n; for(p = head[u]; p != -1; p = edge[p].next) { if(temp > dis[edge[p].v] && edge[p].Max) { curr[u] = p; temp = dis[edge[p].v]; } } dis[u] = temp+1; gap[dis[u]]++; u = pre[u]; } } //printf("%d\n",flow); return flow; } bool vis[100010]; int pri[100010]; struct N { int d,r; }; vector<N> vec[110]; int main() { int i,j,k,n,m; memset(vis,false,sizeof(vis)); int ap; for(i = 2,ap = 0,n = 100000; i <= n; ++i) { if(vis[i]) continue; pri[ap++] = i; for(j = i+i; j <= n; j += i) vis[j] = true; } scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); Top = 0; int S = 1,T = 4001,ans,x,r = 2; for(i = 1; i <= n; ++i) { scanf("%d",&x); for(j = 0;j < ap && x >= pri[j]; ++j) { ans = 0; while(x%pri[j] == 0) { ans++; x /= pri[j]; } if(ans) { vec[i].push_back((N){pri[j],r}); if(i&1) { Link(S,r,ans); Link(r,S,0); } else { Link(r,T,ans); Link(T,r,0); } r++; } } if(x != 1) { vec[i].push_back((N){x,r}); if(i&1) { Link(S,r,1); Link(r,S,0); } else { Link(r,T,1); Link(T,r,0); } r++; } } int u,v; for(i = 1;i <= m; ++i) { scanf("%d %d",&u,&v); if(v&1) swap(u,v); for(j = vec[u].size()-1,k = vec[v].size()-1;j >= 0 && k >= 0; ) { if(vec[u][j].d == vec[v][k].d) { Link(vec[u][j].r,vec[v][k].r,INF); Link(vec[v][k].r,vec[u][j].r,0); --j,--k; } else if(vec[u][j].d > vec[v][k].d) { --j; } else { --k; } } } printf("%d\n",ISAP(S,T,T)); return 0; }
时间: 2024-10-29 10:45:48