题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案。保证n个数互不相同。

思路:容易发现,如果两个数不能同时在集合中,这两个数的二进制表示一定只有一位不同(因为n个数互不相同,所以一定不会有两个数的二进制位一定相同)。那么我们不妨把每个数和它只有一位不同的数连一条边,那么原问题就变成了在一张图上找最多的点,使得任意两点间都没有变直接相连,而这个问题就是最大独立集问题。而且,由于n个数互不相同,所以这张图一定没有长度为奇数的环,即这张图一定是二分图。那么,现在问题就变成了求一张二分图的最大独立集大小并输出具体方案。独立集大小我们都知道是n - 最大匹配数,怎么求具体方案呢?我们知道最大独立集和最小点覆盖是互补关系,那么我们可以求出最小点覆盖,不是最小点覆盖的点就是最大独立集中的点了。

最小点覆盖的构造方法如下(来自《算法竞赛进阶指南》):

1:求出二分图的最大匹配。

2:从左部每个非匹配点出发,再执行一次dfs寻找增广路的过程(这个过程一定会失败),并标记沿途访问过的节点。

3:取左部未被标记过的节点,右部标记过的节点,就得到了二分图的最小点覆盖。

对于这个题,在构造出了图之后,我们先通过搜索确定哪些点在左边,哪些点在右边,之后执行二分图最大匹配。最后,枚举点,如果这个点没有点和它匹配(即非匹配点),从这个点再进行增广。最后把不是最小点覆盖中的点计入答案。

代码:

#include <bits/stdc++.h>
#define pii pair<int, int>
using namespace std;
const int maxn = 5010;
int a[maxn];
bool v[maxn], l[maxn];
bool va[maxn], vb[maxn];
vector<int> rea, reb;
int match[maxn];
vector<int> G[maxn], ans;
void add(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
bool dfs(int x) {
va[x] = 1;
v[x] = 1;
for (int i = 0; i < G[x].size(); i++) {
int y = G[x][i];
if(!vb[y]) {
vb[y] = 1;
if(!match[y] || dfs(match[y])) {
match[y] = x;
return 1;
}
v[y] = 1;
}
}
return 0;
}
void dfs1(int x, int dep) {
if(dep & 1) {
rea.push_back(x);
l[x] = 1;
} else {
reb.push_back(x);
l[x] = 0;
}
v[x] = 1;
for (int i = 0; i < G[x].size(); i++) {
int y = G[x][i];
if(v[y]) continue;
dfs1(y, dep + 1);
}
}
int main() {
int n;
//freopen("in.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++) {
if(__builtin_popcount(a[i] ^ a[j]) == 1) {
add(i, j);
}
}
for (int i = 1; i <= n; i++) {
if(v[i]) continue;
dfs1(i, 1);
}
memset(v, 0, sizeof(v));
if(rea.size() > reb.size()) {
swap(rea, reb);
for (int i = 1; i <= n; i++)
l[i] ^= 1;
}
for (int i = 0; i < rea.size(); i++) {
memset(va, 0, sizeof(va));
memset(vb, 0, sizeof(vb));
dfs(rea[i]);
}
memset(va, 0, sizeof(va));
memset(vb, 0, sizeof(vb));
memset(v, 0, sizeof(v));
for (int i = 0; i < rea.size(); i++) {
bool flag = 0;
int x = rea[i];
for (int j = 0; j < G[x].size(); j++) {
int y = G[x][j];
if(match[y] == x) {
flag = 1;
break;
}
}
if(flag == 0 && v[x] == 0) {
dfs(x);
}
}
for (int i = 1; i <= n; i++) {
if(l[i] == 1 && v[i] == 1) ans.push_back(i);
else if(l[i] == 0 && v[i] == 0) ans.push_back(i);
}
printf("%d\n", ans.size());
for (int i = 0; i < ans.size(); i++) {
printf("%d ", a[ans[i]]);
}
printf("\n");
}

2019牛客多校第五场F maximum clique 1 最大独立集的更多相关文章

  1. 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集

    maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...

  2. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  3. 牛客多校第五场 F take

    链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 题目描述 Kanade has n boxes , the i-th box has p[i] ...

  4. 牛客多校第五场 F take 期望转化成单独事件概率(模板) 树状数组

    链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 Kanade has n boxes , the i-th box has p[i] proba ...

  5. 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂

    理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...

  6. 2019牛客多校第五场generator2——BSGS&&手写Hash

    题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...

  7. 2019牛客多校第五场G-subsequence 1 DP

    G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...

  8. 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化

    B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...

  9. 2019牛客多校第五场H - subsequence 2 拓扑

    H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...

随机推荐

  1. Sass--混合宏--声明宏

    如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的.但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无法达到我们目了.这 ...

  2. MySQL中常见函数

    一.日期函数 1.NOW()   返回当前日期和时间 mysql> SELECT NOW(); +---------------------+ | NOW() | +-------------- ...

  3. struts2结果跳转和参数获取

    一.结果跳转方式 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC ...

  4. maven插件之maven-surefire-plugin,junit单元测试报告和sonar测试覆盖率的整合说明

    POM中配置的如下: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId> ...

  5. 英语单词custom

    custom 来源——xshell快捷键 翻译 n. 习惯,惯例:风俗:海关,关税:经常光顾:[总称](经常性的)顾客 adj. (衣服等)定做的,定制的 高中 | 初中 词源 英语单词custom含 ...

  6. web项目问题总结

    1.项目编码问题:建立项目之初,应统一设置项目组所有电脑的eclipse 默认项目编码,还有各个文件的编码格式 中文乱码的问题,需要三个地方同时设置utf-8编码,第一是数据库里表的编码,第二是jsp ...

  7. shell脚本学习(7)sort

    1 sort的格式 sort [options] [files] sort 参数  文件 2 参数 -t 用单个符char作为默认的字段分隔符, 默认字段分隔符是空白 参数-k 用来定义排序键值字段 ...

  8. spring boot 修改banner

    在resources目录下新建一个banner.txt,里面添加要显示的内容,如: ////////////////////////////////////////////////////////// ...

  9. 2016亚洲城市GDP50强出炉

    2017年年1月,中国各省GDP排名,台湾排第6:广东,江苏,山东,浙江,河南,台湾,四川,湖北,河北,湖南,我国台湾地区去年的GDP增长率为1.4%,总量折合人民币约为37329.1亿元,加入全国榜 ...

  10. mysql8.0 新特性,对json类型的常用操作

    mysql8 新特性-json数据类型操作 -- 根据key(可多个)获取value SELECT JSON_EXTRACT('{"id": 14, "name" ...