[JZOJ 4832]高維宇宙

Description
這裏寫圖片描述
Input
這裏寫圖片描述
Sample Input
5
2 9 11 12 37
Output
這裏寫圖片描述
Sample Output
2
這裏寫圖片描述
這裏寫圖片描述

The Solution

其實這道題題目大意簡化一下就是
將第I個數看成編號爲I的一個點
ai+aj 爲質數,則點I與點j之間連一條無向邊
然後染色跑一遍二分圖匹配就好了

CODE

#include <cstdio>
#include <algorithm>
#include <cstring>
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define N 45 * 45
#define M 2005

using namespace std;

int a[45],Prime[2000],Final[N],Color[N],Vis[N];
int cnt = 0,n,tot = 0,ans = 0;
bool bz[N],Mark[N];

struct node
{
    int to,next;

    node(void){}
    node(int a,int b) : to(a),next(b){}
}e[N * 2];

void Link(int u,int v)
{
    e[++ tot] = node(v,Final[u]),Final[u] = tot;
    e[++ tot] = node(u,Final[v]),Final[v] = tot;
}

void Pretreatment()
{
    fo(i,2,2000)
    {
        if (!bz[i]) Prime[++ cnt] = i;
        int j = 1;
        while (Prime[j] * i <= 2000 && j <= cnt)
        {
            bz[i * Prime[j]] = true;
            if (i % Prime[j] == 0) break;
            j++;
        }
    }
}

void dfs(int x)
{
    for (int i = Final[x];i;i = e[i].next)
    {
        int t = e[i].to;
        if (Color[t] == -1)
        {
            Color[t] = Color[x] ^ 1;
            dfs(t);
        }
    }
}

int Hungarian(int x)
{
    for (int i = Final[x];i;i = e[i].next)
    {
        int t = e[i].to;
        if (!Mark[t])
        {
            Mark[t] = true;
            if (!Vis[t] || Hungarian(Vis[t]))
            {
                Vis[t] = x;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    freopen("prime.in","r",stdin);
    freopen("prime.out","w",stdout);    
    scanf("%d",&n);
    fo(i,1,n) scanf("%d",&a[i]);

    Pretreatment(); 

    memset(Color,255,sizeof(Color));
    fo(i,1,n-1)
        fo(j,i+1,n)
            if (!bz[a[i] + a[j]]) Link(i,j);
    fo(i,1,n)
        if (Color[i] == -1) Color[i] = 0,dfs(i);
    fo(i,1,n)
        if (Color[i] == 0)
        {
            memset(Mark,false,sizeof(Mark));
            if (Hungarian(i)) ans ++;
        }
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章