首页 > 其他 > 详细

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

时间:2015-04-25 18:06:34      阅读:265      评论:0      收藏:0      [点我收藏+]

题目描述:

两个数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\n", _case, n - hunagry());
111     }
112     return 0;
113 }

 

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

原文:http://www.cnblogs.com/huoxiayu/p/4456107.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!