• zoj3988(自己集合和自己集合匹配)


    题:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370128

    题意:给定n个数(n<=3e3)俩者能匹配的充分必要条件未俩者之和为质数,求至多匹配完k对后各个数所属下标的并集最大是多少;

    分析:二分图直接匈牙利算法搞起,主要k限制,那就判断匹配数和k之间关系;

       若ans<=k,那么匹配数足以贪心地输出2*k;

       否则看剩下有多少个,1个就有一个贡献,因为经过最大匹配后另一个一定被匹配完了;

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    const int M=3e3+5;
    typedef long long ll;
    #define pb push_back
    
    const int N=2e6+6;
    const int inf=0x3f3f3f3f;
    int mp[M],vis[M],a[M];
    int n;
    int prime[N];
    vector<int>g[M];
    void init(){
        for(int i=2;i<N;i++){
            if(!prime[i]){
                for(int j=i+i;j<N;j+=i)
                    prime[j]=1;
            }
        }
    }
    int dfs(int u){
        vis[u]=1;
        for(auto v:g[u]){
            if(!vis[v]){
                vis[v]=1;
                if(mp[v]==-1||dfs(mp[v])){
                    mp[v]=u;
                    mp[u]=v;
                    return 1;
                }
            }
        }
        return 0;
    }
    int xiong(){
        int res=0;
        for(int i=1;i<=n;i++)
            if(mp[i]==-1){///一般的匈牙利算法不用这句,这题加代表选过了不能再选,只能从未选过的开始选
                memset(vis,0,sizeof(vis));
                res+=dfs(i);
            }
        return res;
    }
    int main(){
        int T;
        scanf("%d",&T);
        init();
        while(T--){
            int k;
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]),mp[i]=0,g[i].clear();
            int sum=0;
            for(int i=1;i<=n;i++){
                for(int j=i+1;j<=n;j++)
                    if(!prime[a[i]+a[j]]){
                        ///cout<<i<<"  "<<j<<endl;
                        g[i].pb(j),g[j].pb(i);
                        mp[i]=-1,mp[j]=-1;
                    }
            }
    
            int ans=xiong();
            if(ans>=k){ printf("%d
    ",k*2); }
            else{
                int leave=0;
                for(int i=1;i<=n;i++)
                    if(mp[i]==-1) leave++;
                printf("%d
    ",2*ans+min(k-ans,leave));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    手机端布局
    雪碧图优缺点
    es6的基本数据详解
    react生命周期函数
    第七周作业-使用Python实现抽样分布的验证(正态分布、卡方分布、T分布等)
    第六章统计量及其抽样分布
    Python实现概率分布(二项分布、伯努利分布、泊松分布、几何分布、正态分布等)
    4.概率与概率分布
    3.描述性统计
    统计学小组
  • 原文地址:https://www.cnblogs.com/starve/p/13859374.html
Copyright © 2020-2023  润新知