萌新妹子刚学OI网络流板子题求调
查看原帖
萌新妹子刚学OI网络流板子题求调
556545
_anll_楼主2024/1/19 16:34

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;
}
2024/1/19 16:34
加载中...