zoukankan      html  css  js  c++  java
  • 【LOJ】#2081. 「JSOI2016」反质数序列

    题解

    我居然都没反应过来二分图内选集合两两不能有边是最大独立集了

    我退役吧
    显然连边只能在奇数和偶数之间,然后二分图求最大独立集是节点数-最大匹配数

    啊当然还有对于1的话只能留一个1

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define MAXN 3005
    #define mo 99994711
    #define pb push_back
    #define eps 1e-8
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef unsigned long long u64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 - '0' + c;
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int N;
    int a[MAXN],matc[MAXN];
    bool isprime[1000005],vis[MAXN];
    int prime[100005],tot;
    struct node {
        int to,next;
    }E[MAXN * MAXN / 4];
    int head[MAXN],sumE;
    void add(int u,int v) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        head[u] = sumE;
    }
    bool match(int u) {
        for(int i = head[u] ; i ; i = E[i].next) {
            int v = E[i].to;
            if(!vis[v]) {
                vis[v] = 1;
                if(!matc[v] || match(matc[v])) {
                    matc[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    void Solve() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) read(a[i]);
        sort(a + 1,a + N + 1);
        int p = 1;
        while(p <= N) {
            if(a[p] != 1) break;
            ++p;
        }
        if(a[1] == 1) --p;
        for(int i = p ; i <= N ; ++i) a[i - p + 1] = a[i];
        N = N - p + 1;
        for(int i = 1 ; i <= N ; ++i) {
            if(a[i] % 2 == 0) {
                for(int j = 1 ; j <= N ; ++j) {
                    if(isprime[a[i] + a[j]]) add(i,j);
                }
            }
        }
        int ans = N;
        for(int i = 1 ; i <= N ; ++i) {
            if(a[i] % 2 == 0) {
                memset(vis,0,sizeof(vis));
                if(match(i)) --ans;
            }
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        memset(isprime,1,sizeof(isprime));
        for(int i = 2 ; i <= 1000000 ; ++i) {
            if(isprime[i]) {
                prime[++tot] = i;
            }
            for(int j = 1 ; j <= tot ; ++j) {
                if(prime[j] > 1000000 / i) break;
                isprime[i * prime[j]] = 0;
                if(i % prime[j] == 0) break;
            }
        }
        Solve();
    }
    
  • 相关阅读:
    【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】
    【模拟题(63550802...)】解题报告【贪心】【拓扑排序】【找规律】【树相关】
    【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
    IMemoryBufferReference and IMemoryBufferByteAccess
    SoftwareBitmap and BitmapEncoder in Windows.Graphics.Imaging Namespace
    Windows UPnP APIs
    编译Android技术总结
    Windows函数转发器
    Two Ways in Delphi to Get IP Address on Android
    Delphi Call getifaddrs and freeifaddrs on Android
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9553655.html
Copyright © 2011-2022 走看看