zoukankan      html  css  js  c++  java
  • 2015编程之美 初赛第一场C题 质数相关 二分图的最大匹配

    质数相关

    Time Limit: 1 Sec  Memory Limit: 256 MB

    题目连接

    http://hihocoder.com/contest/msbop2015round2a/problem/3

    Description

    两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数。一个集合S被称为质数相关,是指S中存在两个质数相关的数,否则称S为质数无关。如{2, 8, 17}质数无关,但{2, 8, 16}, {3, 6}质数相关。现在给定一个集合S,问S的所有质数无关子集中,最大的子集的大小。

    Input

    第一行为一个数T,为数据组数。之后每组数据包含两行。

    第一行为N,为集合S的大小。第二行为N个整数,表示集合内的数。

    Output

    对于每组数据输出一行,形如"Case #X: Y"。X为数据编号,从1开始,Y为最大的子集的大小。

    Sample Input

    3
    5
    2 4 8 16 32
    5
    2 3 4 6 9
    3
    1 2 3

    Sample Output

    Case #1: 3
    Case #2: 3
    Case #3: 2

    HINT

    1 ≤ T ≤ 20

    集合S内的数两两不同且范围在1到500000之间。

    小数据

    1 ≤ N ≤ 15

    大数据

    1 ≤ N ≤ 1000

    题意

    题解:

    首先我们把题目转化一下,我们由所给的质数关系,我们可以得到 每一个数可以和哪些数在一起的图

    然后我们就可以转化成二分图的最大匹配了!

    唔 另一道题可见:http://www.cnblogs.com/qscqesze/p/4414246.html

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 200001
    #define mod 10007
    #define eps 1e-9
    int Num;
    char CH[20];
    //const int inf=0x7fffffff;   //нчоч╢С
    const int inf=0x3f3f3f3f;
    /*
    
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    */
    //**************************************************************************************
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void P(int x)
    {
        Num=0;if(!x){putchar('0');puts("");return;}
        while(x>0)CH[++Num]=x%10,x/=10;
        while(Num)putchar(CH[Num--]+48);
        puts("");
    }
    const int MAXN = 500001;
    bool flag[MAXN];
    int primes[MAXN], pi;
    void GetPrime_1()
    {
        int i, j;
        pi = 0;
        memset(flag, false, sizeof(flag));
        for (i = 2; i < MAXN; i++)
            if (!flag[i])
            {
                primes[i] = 1;//素数标识为1
                for (j = i; j < MAXN; j += i)
                    flag[j] = true;
            }
    }
    
    vector<int> q[maxn];
    int vis[maxn];
    int match[maxn];
    int a[maxn];
    bool cmp(int b,int c)
    {
        return b>c;
    }
    int dfs(int x)
    {
        for(int i=0;i<q[x].size();i++)
        {
            if(vis[q[x][i]]==0)
            {
                vis[q[x][i]]=1;
                if(match[q[x][i]]==-1||dfs(match[q[x][i]]))
                {
                    match[q[x][i]]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        GetPrime_1();
        primes[1]=0;
        int t=read();
        for(int cas=1;cas<=t;cas++)
        {
            memset(match,-1,sizeof(match));
            int n=read();
            for(int i=0;i<n;i++)
                q[i].clear();
            for(int i=0;i<n;i++)
                a[i]=read();
            sort(a,a+n,cmp);
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(i==j)
                        continue;
                    int b=a[j];
                    int c=a[i];
                    if(b<c)
                        swap(b,c);
                    if(b%c==0&&primes[b/c])
                    {
                        q[j].push_back(i);
                    }
                }
            }
            int ans=0;
            for(int i=0;i<n;i++)
            {
                memset(vis,0,sizeof(vis));
                if(dfs(i))
                    ans++;
            }
            printf("Case #%d: %d
    ",cas,n-ans/2);
        }
    
    }
  • 相关阅读:
    Metasploit advanced命令使用技巧
    Metasploit命令info使用技巧
    Kali Linux 2020.1b发布了
    设置USB无线网卡为监听模式大学霸IT达人
    解决ifconfig命令未找到
    Metasploit新增技巧提示功能
    Wireshark运算符!=无法正常工作
    解决Kali Linux XFCE桌面Tab无法补全
    Nessus更新到8.9.1
    ASP入门(七)-Response小案例
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4458484.html
Copyright © 2011-2022 走看看