2019牛客多校第五场F maximum clique 1 最大独立集
题意:给你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 最大独立集的更多相关文章
- 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集
maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
- 牛客多校第五场 F take
链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 题目描述 Kanade has n boxes , the i-th box has p[i] ...
- 牛客多校第五场 F take 期望转化成单独事件概率(模板) 树状数组
链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 Kanade has n boxes , the i-th box has p[i] proba ...
- 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂
理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...
- 2019牛客多校第五场generator2——BSGS&&手写Hash
题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...
- 2019牛客多校第五场G-subsequence 1 DP
G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...
- 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}\) 思路 一般看 ...
- 2019牛客多校第五场H - subsequence 2 拓扑
H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...
随机推荐
- bzoj1002 轮状病毒 暴力打标找规律/基尔霍夫矩阵+高斯消元
基本思路: 1.先观察规律,写写画画未果 2.写程序暴力打表找规律,找出规律 1-15的答案:1 5 16 45 121 320 841 2205 5776 151 ...
- Python3解leetcode Binary Tree Paths
问题描述: Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children. E ...
- 【Dart学习】--之Duration相关方法总结
一,概述 Duration表示从一个时间点到另一个时间点的时间差 如果是一个较晚的时间点和一个较早的时间点,Duration可能是负数 二,创建Duration 唯一的构造函数创建Duration对象 ...
- 九、async、future、packaged_task、promise
std::async.std::future创建后台任务并返回值. 希望线程返回一个值. std::async是个函数模板,用来启动一个异步任务,返回一个std::future对象 异步任务:自动创建 ...
- CF 1172E Nauuo and ODT ——LCT
题目:http://codeforces.com/contest/1172/problem/E LCT好题. 考虑对每个颜色求出 “不是该颜色的点组成的连通块的 siz2 之和” .每个颜色用 LCT ...
- NOIp 图论算法专题总结 (3):网络流 & 二分图 简明讲义
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 网络流 概念 1 容量网络(capacity network)是一个有向图,图的 ...
- 如何让UIViewController自动弹出PickerView
因为响应者的一下属性inputView和inputAccessoryView都是只读的,所以如果想要指定弹出的view就要override 下面两个属性的get和set方法 UIResponder ( ...
- vue项目在IE下显示空白打不开问题
近期遇到了项目是vue做的,在IE浏览器下打不开,显示空白问题,解决方案如下: 打不开的原因是因为少了babel-polyfill处理器,所以第一步需要下载: npm install babel-po ...
- zabbix配置-模板
1.配置=>模板=>创建模板=>输入模板名称和群组 2.配置=>模板=>找到刚刚创建的模板=>点击应用集(applications)=>创建应用集=>输 ...
- 解决“/bin/bash^M: bad interpreter: No such file or directory”
在执行shell脚本时提示这样的错误主要是由于shell脚本文件是dos格式,即每一行结尾以\r\n来标识,而unix格式的文件行尾则以\n来标识. 查看脚本文件是dos格式还是unix格式的几种办 ...