• 编程之美2015 round2a c 二分图最大独立集


    题目描述:

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

    思路:

    最大独立集,大致分析了一下感觉是二分图,没有详细证明,不过大数据过了,应该是对的吧,求大神证明是二分图。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 
      6 const int N = 1001;
      7 const int M = 500001;
      8 const int E = 100000;
      9 bool prime[M];
     10 bool visit[N];
     11 int head[N];
     12 int mark[N];
     13 int label[N];
     14 int n, e;
     15 
     16 struct Edge
     17 {
     18     int v, next;
     19 } edge[E];
     20 
     21 void init()
     22 {
     23     e = 0;
     24     memset( head, -1, sizeof(head) );
     25 }
     26 
     27 void addEdge( int u, int v )
     28 {
     29     edge[e].v = v;
     30     edge[e].next = head[u];
     31     head[u] = e++;
     32 }
     33 
     34 int dfs( int u )
     35 {
     36     for ( int i = head[u]; i != -1; i = edge[i].next )
     37     {
     38         int v = edge[i].v;
     39         if ( !visit[v] )
     40         {
     41             visit[v] = true;
     42             if ( mark[v] == -1 || dfs( mark[v] ) )
     43             {
     44                 mark[v] = u;
     45                 mark[u] = v;
     46                 return 1;
     47             }
     48         }
     49     }
     50     return 0;
     51 }
     52 
     53 int hunagry()
     54 {
     55     memset( mark, -1, sizeof(mark) );
     56     int res = 0;
     57     for ( int i = 1; i <= n; i++ )
     58     {
     59         if ( mark[i] != -1 ) continue;
     60         memset( visit, 0, sizeof(visit) );
     61         res += dfs(i);
     62     }
     63     return res;
     64 }
     65 
     66 void get()
     67 {
     68     memset( prime, true, sizeof(prime) );
     69     prime[0] = prime[1] = false;
     70     for ( int i = 2; i < M; i++ )
     71     {
     72         if ( prime[i] )
     73         {
     74             int j = i * i;
     75             if ( j >= M ) break;
     76             do
     77             {
     78                 prime[j] = false;
     79                 j += i;
     80             } while ( j < M );
     81         }
     82     }
     83 }
     84 
     85 int main()
     86 {
     87     get();
     88     int t;
     89     scanf("%d", &t);
     90     for ( int _case = 1; _case <= t; _case++ )
     91     {
     92         scanf("%d", &n);
     93         init();
     94         for ( int i = 1; i <= n; i++ )
     95         {
     96             scanf("%d", label + i);
     97             for ( int j = i - 1; j > 0; j-- )
     98             {
     99                 int tx = label[i], ty = label[j];
    100                 if ( tx > ty ) swap( tx, ty );
    101                 if ( ty % tx ) continue;
    102                 int r = ty / tx;
    103                 if ( prime[r] )
    104                 {
    105                     addEdge( i, j );
    106                     addEdge( j, i );
    107                 }
    108             }
    109         }
    110         printf("Case #%d: %d
    ", _case, n - hunagry());
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    字符数组与指针
    终于在博客园安家了
    关于SET NOCOUNT
    如何判断请求是否发送成功以及获取请求中的数据
    mysql进阶 withas 性能调优
    Linux mkdir
    Linux umask and chmod
    C linux Debug
    Linux sed
    Linux ulimit
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4456107.html
Copyright © 2020-2023  润新知