hihocoder 1158 质数相关(二分图匹配 最大独立集)
2015-09-21 20:52
260 查看
题目链接:传送门
题意:
给定你一个为n的集合选定一个最大的子集使得不存在 ai*p=aj的情况,p为一个素数。
分析:
对于所有的ai*p=aj的情况建图,求出这个二分图的最大匹配,然后n-最大匹配数/2即可。
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1010;
const int N = 500000+10;
int a[maxn];
int prime
,cnt;
bool is
;
void get_prime() {
memset(is,0,sizeof(is));
cnt = 0;
is[1]=1;
for(int i=2; i<N; i++) {
if(!is[i]) {
prime[cnt++]=i;
for(int j=i+i; j<N; j+=i)
is[j]=1;
}
}
}
bool vis[maxn];
int link[maxn],head[maxn*2];
int ip;
struct nod {
int to;
int next;
} edg[maxn*maxn];
void init1() {
ip=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v) {
edg[ip].to=v;
edg[ip].next=head[u];
head[u]=ip++;
}
bool dfs(int u) {
for(int i=head[u]; i!=-1; i=edg[i].next) {
int v=edg[i].to;
if(!vis[v]) {
vis[v]=1;
if(link[v]==-1||dfs(link[v])) {
link[v]=u;
return true;
}
}
}
return false;
}
int max_match(int n) {
int ans = 0;
memset(link,-1,sizeof(link));
for(int i=1; i<=n; i++) {
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
int main() {
get_prime();
int t,n,cas=1;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",a+i);
}
init1();
sort(a+1,a+1+n);
for(int i=1; i<=n; i++) {
for(int j=i+1; j<=n; j++) {
if(a[j]%a[i]==0&&!is[a[j]/a[i]]) {
add(j,i);
add(i,j);
}
}
}
int mmax = max_match(n);
printf("Case #%d: %d\n",cas++,n-mmax/2);
}
return 0;
}
/****
3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3
***/
题意:
给定你一个为n的集合选定一个最大的子集使得不存在 ai*p=aj的情况,p为一个素数。
分析:
对于所有的ai*p=aj的情况建图,求出这个二分图的最大匹配,然后n-最大匹配数/2即可。
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1010;
const int N = 500000+10;
int a[maxn];
int prime
,cnt;
bool is
;
void get_prime() {
memset(is,0,sizeof(is));
cnt = 0;
is[1]=1;
for(int i=2; i<N; i++) {
if(!is[i]) {
prime[cnt++]=i;
for(int j=i+i; j<N; j+=i)
is[j]=1;
}
}
}
bool vis[maxn];
int link[maxn],head[maxn*2];
int ip;
struct nod {
int to;
int next;
} edg[maxn*maxn];
void init1() {
ip=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v) {
edg[ip].to=v;
edg[ip].next=head[u];
head[u]=ip++;
}
bool dfs(int u) {
for(int i=head[u]; i!=-1; i=edg[i].next) {
int v=edg[i].to;
if(!vis[v]) {
vis[v]=1;
if(link[v]==-1||dfs(link[v])) {
link[v]=u;
return true;
}
}
}
return false;
}
int max_match(int n) {
int ans = 0;
memset(link,-1,sizeof(link));
for(int i=1; i<=n; i++) {
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
int main() {
get_prime();
int t,n,cas=1;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",a+i);
}
init1();
sort(a+1,a+1+n);
for(int i=1; i<=n; i++) {
for(int j=i+1; j<=n; j++) {
if(a[j]%a[i]==0&&!is[a[j]/a[i]]) {
add(j,i);
add(i,j);
}
}
}
int mmax = max_match(n);
printf("Case #%d: %d\n",cas++,n-mmax/2);
}
return 0;
}
/****
3
5
2 4 8 16 32
5
2 3 4 6 9
3
1 2 3
***/
相关文章推荐
- 转载的关于iOS架构的东西
- 判断一个数是否是2的N次方
- Spark浅显了解
- 象限覆盖 CodeChef Lighthouses
- SpringMVC 返回数据的缺省格式
- 图像编码基本分类
- 5条原则助你改善产品UX设计
- 怎样的配色能让你的作品高端!上档次呢?
- 自定义 EditText背景 选中和默认
- oracle 数据库 sqlplus的一些要点
- C#软件开发实例.私人订制自己的屏幕截图工具(三)托盘图标及菜单的实现
- 关于字符串的trim()和截取空格(2015年9月19日)
- 最大熵模型总结
- SOHO设计师如何保障自己的权益
- 响应式布局的9项基本原则
- 在linux中文件或文件夹名字中不要有空格
- Linux中tty框架与uart框架之间的调用关系剖析
- String split 分隔字符串,多个分隔符、正则表达式学习示例
- Objective-C-----用NSArray显示一年中所有的月份
- 比较三个数大小