编程之美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\n", _case, n - hunagry());
111     }
112     return 0;
113 }
时间: 2024-08-07 08:40:14

编程之美2015 round2a c 二分图最大独立集的相关文章

编程之美2015初赛_质数相关(二分图)

质数相关 题意:求二分图的最大独立集(独立集就是图中任意两个顶点都不相连的顶点集合) 思路:交替染色法,两种颜色把图染色.颜色最多的即为最大独立集. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<set> #include<map&

编程之美2015初赛第一场BC

题目2 : 建造金字塔 时间限制:4000ms 单点时限:2000ms 内存限制:256MB 描述 在二次元中,金字塔是一个底边在x轴上的等腰直角三角形. 你是二次元世界的一个建筑承包商.现在有N个建造订单,每个订单有一个收益w,即建造此金字塔可获得w的收益.对每个订单可以选择建造或不建造. 建造一个金字塔的成本是金字塔的面积,如果两个或多个金字塔有重叠面积,则建造这些金字塔时重叠部份仅需建造一次. 建造一组金字塔的总利润是收益总和扣除成本.现给出这些订单,请求出最大利润. 输入 输入数据第一行

编程之美2015初赛第一场 题解

[A题] 彩色的树 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵n个节点的树,节点编号为1, 2, -, n.树中有n - 1条边,任意两个节点间恰好有一条路径.这是一棵彩色的树,每个节点恰好可以染一种颜色.初始时,所有节点的颜色都为0.现在需要实现两种操作: 1. 改变节点x的颜色为y: 2. 询问整棵树被划分成了多少棵颜色相同的子树.即每棵子树内的节点颜色都相同,而相邻子树的颜色不同. 输入 第一行一个整数T,表示数据组数,以下是T组数据. 每组数据第

hiho 编程之美2015初赛第一场(质数相关-2分图匹配)

两个数a和 b (a<b)被称为质数相关,是指a × p = b,这里p是一个质数.一个集合S被称为质数相关,是指S中存在两个质数相关的数,否则称S为质数无关.如{2, 8, 17}质数无关,但{2, 8, 16}, {3, 6}质数相关.现在给定一个集合S,问S的所有质数无关子集中,最大的子集的大小. 输入 第一行为一个数T,为数据组数.之后每组数据包含两行. 第一行为N,为集合S的大小.第二行为N个整数,表示集合内的数. 输出 对于每组数据输出一行,形如"Case #X: Y"

编程之美2015 #2 回文字符序列

题目: 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据输出一行,格式为&

编程之美2015 #3 基站选址

题目: 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方. 网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离). 在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价. 输入 第一行为一个整数T,表示数据组数. 每组数据第一行为四个整数:N, M, A, B. 接

2月29日(编程之美2015资格赛)

时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "February",

编程之美2015资格赛

题目1 : 2月29日 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个日期,计算这两个日期之间有多少个2月29日(包括起始日期). 只有闰年有2月29日,满足以下一个条件的年份为闰年: 1. 年份能被4整除但不能被100整除 2. 年份能被400整除 输入 第一行为一个整数T,表示数据组数. 之 后每组数据包含两行.每一行格式为"month day, year",表示一个日期.month为{"January", "Fe

编程之美2015初赛第二场AB

题目1 : 扑克牌 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52张牌中的若干张,请计算将它们排成一列,相邻的牌面值不同的方案数. 牌的表示方法为XY,其中X为面值,为2.3.4.5.6.7.8.9.T.J.Q.K.A中的一个.Y为花色,为S.H.D.C中的一个.如2S.2H.TD等. 输入 第一行为一个整数T,为数据组数. 之后每组数据占一行.这一行首先包含一个