zoukankan      html  css  js  c++  java
  • BZOJ 4857 反质数序列

    题面

    奇数+奇数一定不是质数(1+1除外),偶数+偶数一定不是质数,质数只可能出现在偶数+奇数中

    把所有的点排成两列,权值为奇数的点在左边,权值为偶数的在右边

    如果左边的点x+右边的点y是质数,我们就连一条x->y的边

    最后答案显然是最大独立集=n-最小点覆盖=n-最大匹配数

    由于1比较特殊,考虑到最终答案1的出现次数<=1,所以如果有多个1只保留一个即可

    #include <bits/stdc++.h>
    using namespace std;
    struct littlstar{
        int to;
        int nxt;
        int w;
    }star[30000000];
    int head[30000000],cnt=1;
    void add(int u,int v,int w)
    {
        star[++cnt].to=v;
        star[cnt].nxt=head[u];
        star[cnt].w=w;
        head[u]=cnt;
    }
    int n;
    int prime[1000010];
    int a[1000010];
    void pre()
    {
        for(register int i=2;i<=1000000;i++){
            if(prime[i]) continue;
            for(register int j=i;j<=1000000/i;j++){
                prime[i*j]=1;
            }
        }
    }
    int dis[1000010];
    queue<int> q;
    bool bfs()
    {
        memset(dis,0,sizeof(dis));
        while(q.size()) q.pop();
        q.push(3001);
        dis[3001]=1;
        while(q.size())
        {
            int u=q.front();
            q.pop();
            for(register int i=head[u];i;i=star[i].nxt){
                int v=star[i].to;
                if(star[i].w&&!dis[v]){
                    q.push(v);
                    dis[v]=dis[u]+1;
                    if(v==3002) return 1;
                }
            }
        }
        return 0;
    }
    int dinic(int u,int flow)
    {
        if(u==3002){
            return flow;
        }
        int rest=flow,k;
        for(register int i=head[u];i&&rest;i=star[i].nxt){
            int v=star[i].to;
            if(star[i].w&&dis[v]==dis[u]+1){
                k=dinic(v,min(rest,star[i].w));
                if(!k) dis[v]=0;
                star[i].w-=k;
                star[i^1].w+=k;
                rest-=k;
            }
        }
        return flow-rest;
    }
    int maxflow=0;
    int b[100010];
    int main ()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        sort(a+1,a+1+n);
        int tmpnum=0;
        for(int i=1;i<=n;i++){
            if(i>1&&a[i]==1){
                continue;
            }
            b[++tmpnum]=a[i];
        }
        n=tmpnum;
        for(int i=1;i<=n;i++){
            a[i]=b[i];
        }
        pre();
        for(register int i=1;i<=n;i++){
            for(register int j=1;j<=n;j++){
                if(i==j) continue;
                if(!prime[a[i]+a[j]]&&a[i]%2==1&&a[j]%2==0){
                    add(i,j,1);
                    add(j,i,0);
                }
            }
        }
        for(register int i=1;i<=n;i++){
            if(a[i]%2==1){
                add(3001,i,1);
                add(i,3001,0);
                
            }
            else{
                add(i,3002,1);
                add(3002,i,0);
            }
        }
        int flow=0;
        while(bfs()){
            while(flow=dinic(3001,1000000001)){
                maxflow+=flow;            
            }
        }
        cout<<n-maxflow;
    }
  • 相关阅读:
    vue打包配置发布路径
    qt编程参考资料
    qt下载地址
    树结构遍历节点名字提取,这里提取的是el-tree数据结构,封装成函数
    set实现数组去重后是对象,这里转化为数组
    js中的async await
    微信小程序调微信支付
    Http权威指南(TCP连接)
    Http权威指南(报文)
    Http权威指南(概述篇总结)
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11357731.html
Copyright © 2011-2022 走看看