题意

给出n个不同的数字\(a_i\),求出最大的子集,使得子集内任意两个数在二进制下至少有两位不同。

题解

先对任意两个二进制位只有一个不同的两个数连边,那么问题就转化成找出最多的点集,任意两点没有边,也就是最大独立集问题。普通的图求最大独立集是N-P困难的,但是二分图求最大独立集合是多项式复杂度的。

所以我们把图转换成二分图形式,把二进制下有奇数个1的数放在左边,有偶数个1的数放在右边,这样左边内的点和右边内的点一定不会有连边,因为两边的点二进制1的个数奇偶性是一样的,且不存在相同的数,那么同一边内的两个数就至少会有两位不同。

接下来就是求二分图的最大独立集,参考博客:二分图的最小顶点覆盖 最大独立集 最大团

简单说就是先用匈牙利求出最大匹配,得到包含在最大匹配内的边,对二分图右边每一个不是最大匹配边的端点的点进行一次dfs,dfs路线是未匹配边->匹配边->未匹配边这样交替,对dfs经过的所有点标记vis。最后二分图左边未标记vis,右边标记了vis的点,就是这张二分图的最大独立集

代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int mx = 5005;
const int INF = 0x3f3f3f3f; vector <int> mp[mx];
vector <int> L, R, ans;
int a[mx], linker[mx];
bool used[mx], vis[mx];
int n; bool dfs(int u) {
for (int i = 0; i < mp[u].size(); i++) {
int v = mp[u][i];
if (!used[v]) {
used[v] = true;
if (linker[v] == -1 || dfs(linker[v])) {
linker[v] = u;
return true;
}
}
}
return false;
} int hungary() {
int res = 0;
memset(linker, -1, sizeof(linker));
for (int u = 0; u < L.size(); u++) {
memset(used, false, sizeof(used));
if (dfs(L[u])) res++;
}
return res;
} void dfs2(int u, int flag) {
vis[u] = true;
for (int i = 0; i < mp[u].size(); i++) {
int v = mp[u][i];
if (vis[v]) continue;
if (flag) {
if (linker[u] != v) dfs2(v, flag^1);
} else {
if (linker[v] == u) dfs2(v, flag^1);
}
}
} int main() {
memset(vis, false, sizeof(vis));
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (__builtin_popcount(a[i]) % 2 == 1) L.push_back(i);
else R.push_back(i);
} for (int i = 0; i < L.size(); i++) {
for (int j = 0; j < R.size(); j++) {
if (__builtin_popcount(a[L[i]]^a[R[j]]) == 1) mp[L[i]].push_back(R[j]), mp[R[j]].push_back(L[i]);
}
}
printf("%d\n", n - hungary());
for (int i = 0; i < R.size(); i++) {
int v = R[i];
//printf("linker[%d] = %d\n", v, linker[v]);
if (linker[v] == -1) dfs2(v, 1);
}
for (int i = 0; i < L.size(); i++)
if (!vis[L[i]]) ans.push_back(L[i]);
for (int i = 0; i < R.size(); i++)
if (vis[R[i]]) ans.push_back(R[i]); for (int i = 0; i < ans.size(); i++) printf("%d%c", a[ans[i]], i==ans.size()-1?'\n':' ');
return 0;
}

F-maximum clique 1_2019牛客暑期多校训练营(第五场)的更多相关文章

  1. 2019牛客暑期多校训练营(第五场) maximum clique 1

    题意:给出n个不相同的数,问选出尽量多的数且任两个数字二进制下不同位数大于等于2. 解法:能想到大于等于2反向思考的话,不难发现这是一个二分图,那么根据原图的最大团等于补图的最大独立点集,此问题就变成 ...

  2. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  3. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  4. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  5. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  6. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  7. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  8. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  9. 2019牛客暑期多校训练营(第三场)- F Planting Trees

    题目链接:https://ac.nowcoder.com/acm/contest/883/F 题意:给定n×n的矩阵,求最大子矩阵使得子矩阵中最大值和最小值的差值<=M. 思路:先看数据大小,注 ...

随机推荐

  1. 03-Django模型类

    ORM框架:对象-关系-映射 将面向对象语言程序中的对象自动持久化到关系数据库中.本质就是将数据从一种形式转换到另外一种形式O表示Object 对象类R表示Relations 关系,关系数据库中的表M ...

  2. 接口测试时遇到 java 代码加密请求数据,用 python 的我该怎么办?

    前言 自动化测试应用越来越多了,尤其是接口自动化测试. 在接口测试数据传递方面,很多公司都会选择对请求数据进行加密处理. 而目前为主,大部分公司的产品都是java语言实现的.所以加密处理也是java实 ...

  3. Downgrade extraction on phones running Android 7/8/9

    Now it's more and more difficult for forensic tools to extract evidence from smartphone running Andr ...

  4. 【vue】------ 路由创建 ------ 【William】

    路由常用的配置项: path:路由请求的路径 component:路由匹配成功后需要渲染的组件或者页面 tag:改变组件内部渲染的元素 假设组件内部渲染的是a标签 tag="li" ...

  5. Spring注解浅入浅出——不吹牛逼不装逼

    Spring注解浅入浅出——不吹牛逼不装逼 前情提要 上文书咱们说了<Spring浅入浅出>,对Spring的核心思想看过上篇的朋友应该已经掌握了,此篇用上篇铺垫,引入注解,继续深入学习. ...

  6. JDK、JRE、JVM之间的区别和联系

    JDK : Java Development ToolKit(Java开发工具包).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工 ...

  7. Spring aop 影响本地事务的回滚总结

    1  @Before   不会,因为还没执行到service的业务逻辑 2  @ After    默认情况下,报错会影响事务回滚., 当设置@Order属性并设置值优先级大小, 即使报错也不会回滚了 ...

  8. Java小白进阶之值传递-引用传递

    class ClassA{ int value;//成员变量 } public class TestClassA{ public static void main(String args[]){ in ...

  9. hadoop2.7+spark2.2+zookeeper3.4.简单安装

    1.zookeeper的安装##配置/etc/hosts192.168.88.130 lgh192.168.88.131 lgh1192.168.88.132 lgh2 ##安装java8 解压配置环 ...

  10. Netty源码分析--内存模型(下)(十二)

    这一节我们一起看下分配过程 PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacit ...