rt,T了最后三个点,是用质因数进行匹配的,求优化。
#include<iostream>
#include<queue>
#include<map>
#include<cstring>
#define int long long
#define C 2147483647
using namespace std;
struct Edge{
int l,w,nxt;
}edges[3000005];
int T,n,m,s=2001,t=2002,cn=2010,cnt,tt=1,head[400005];
int dep[400005],cur[400005];
int num[10000005],zlen,zs[5000005];
queue<int> qo;
void init(){
num[1]=1;
for(int i=1;i<=5000005;i++){
if(num[i]==0){
zlen+=1,zs[zlen]=i;
}
for(int j=1;j<=zlen&&zs[j]*i<=n;j++){
num[zs[j]*i]=1;
if(i%zs[j]==0){
break;
}
}
}
}
void add_edge(int f,int l,int w){
tt+=1;
edges[tt]={l,w,head[f]};
head[f]=tt;
}
void Add1(int x,int id){
for(int i=1;zs[i]<=x;i++){
if(x%zs[i]==0){
add_edge(id,cn+i,1);
add_edge(cn+i,id,0);
}
}
}
void Add2(int x,int id){
for(int i=1;zs[i]<=x;i++){
if(x%zs[i]==0){
add_edge(i+cn,id,1);
add_edge(id,cn+i,0);
}
}
}
bool bfs(){
memset(dep,0,sizeof(dep));
while(!qo.empty()) qo.pop();
qo.push(s);dep[s]=1;
while(!qo.empty()){
int f=qo.front();qo.pop();
for(int i=head[f];i;i=edges[i].nxt){
int l=edges[i].l,w=edges[i].w;
if(!dep[l]&&w){
dep[l]=dep[f]+1;
if(l==t) return true;
qo.push(l);
}
}
}
return false;
}
int dfs(int x,int mf){
if(x==t) return mf;
int sum=0;
for(int i=cur[x];i;i=edges[i].nxt){
cur[x]=i;
int l=edges[i].l;
if(dep[l]!=dep[x]+1||!edges[i].w) continue;
int ff=dfs(l,min(mf,edges[i].w));
sum+=ff,mf-=ff;
edges[i].w-=ff,edges[i^1].w+=ff;
if(!mf) break;
}
if(!sum) dep[x]=0;
return sum;
}
int dinic(){
int ans=0;
while(bfs()){
memcpy(cur,head,sizeof(head));
ans+=dfs(s,C);
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
init();
int x;
cin>>T;
while(T--){
for(int i=1;i<=tt;i++) edges[i]={0,0,0};
for(int i=1;i<=cnt;i++) head[i]=0;
cnt=0,tt=1;
memset(head,0,sizeof(head));
cin>>n>>m;
s=n+m+1,t=n+m+2,cn=n+m+3;
for(int i=1;i<=n;i++){
cnt+=1;
cin>>x;
add_edge(s,cnt,1);
add_edge(cnt,s,0);
Add1(x,cnt);
}
for(int i=1;i<=m;i++){
cnt+=1;
cin>>x;
add_edge(cnt,t,1);
add_edge(t,cnt,0);
Add2(x,cnt);
}
cout<<dinic()<<endl;
}
return 0;
}