2019暑假牛客第5场-F.maximum clique 1-最大独立集(输出方案)
题面:
思路:
建图方法若两个数有且仅有一个位不同,那么连边(从左边指向右边)。
根据某个数的二进制表达式中有奇数个1还是偶数个1,分成左边和右边。
对于二分图,跑匈牙利求最大匹配,最大独立集=节点数-最大匹配。
对于连通图,最大匹配+最小边覆盖 = N(节点的数量)
最大独立集+最小顶点覆盖=N
对于二分图,最小顶点覆盖=最大匹配
所以,最大独立集+最大匹配 = N;
最大独立集方案的输出,从左边的没有匹配的点出发跑增广路,最后
左边访问的点,和右边没有被访问的点就是最大独立集的一种方案
#include<bits/stdc++.h>
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define rep(i,a,b) for(int i = (a);i >= (b);--i)
using namespace std;
const int maxn = 5e3 + 10;
int n = 0;
int a[maxn];
int color[maxn],head[maxn],cntt = 0;
int cx[maxn],cy[maxn];//cx表示左边匹配到的右边的节点
bool vis[maxn];
struct Edge{int to,nex;
}e[maxn*maxn];
void init(){cntt = 0;per(i,1,n){head[i] = -1;vis[i] = false;}
}
void add_edge(int from,int to){e[++cntt].to = to;e[cntt].nex = head[from];head[from] = cntt;
}
bool judge(int x){//判断两个数的异或和是否只有一个1int cnt = 0;while(x > 0){//每次都去除最右边的1,比直接位运算要快x = x & (x-1);++cnt;}return cnt == 1;
}
int path(int u){vis[u] = true;for(int i = head[u];i != -1;i = e[i].nex){int v = e[i].to;if(!color[v] && !vis[v]){vis[v] = true;if(cy[v] == -1 || path(cy[v])){cx[u] = v;cy[v] = u;return 1;}}}return 0;
}
int max_match(){int sum = 0;memset(cx,-1,sizeof(cx)); memset(cy,-1,sizeof(cy));per(i,1,n){if(color[i]&1){memset(vis,false,sizeof(vis));//每次寻找增广路要初始化sum += path(i);}}return sum;
}
int main(){while(~scanf("%d",&n)){init();per(i,1,n){scanf("%d",&a[i]);}per(i,1,n){int tmp = a[i];int cnt = 0;while(tmp > 0){//根据该数有奇数个1还是偶数个1分成左边和右边cnt += (tmp&1);tmp >>= 1;}color[i] = cnt&1;}per(i,2,n){per(j,1,i-1){if(judge(a[i] ^ a[j])){if(color[i]&1){add_edge(i,j);}else{add_edge(j,i);}}}}/*对于连通图,最大匹配+最小边覆盖 = N(节点的数量)最大独立集+最小顶点覆盖=N对于二分图,最小顶点覆盖=最大匹配所以,最大独立集+最大匹配 = N;*/int ans = max_match();ans = n - ans;printf("%d\n",ans);memset(vis,false,sizeof(vis));/*最大独立集方案的输出,从左边的没有匹配的点出发跑增广路,最后左边访问的点,和右边没有被访问的点就是最大独立集的一种方案*/per(i,1,n){if(color[i] && cx[i] == -1){path(i);}}per(i,1,n){if(color[i] && vis[i]){printf("%d ",a[i]);}if(!color[i] && !vis[i]){printf("%d ",a[i]);}}printf("\n");}return 0;
}
2019暑假牛客第5场-F.maximum clique 1-最大独立集(输出方案)相关推荐
- 2019暑假牛客多校赛第九场H.Cutting Bamboos (主席树+二分)
题意: 有n条柱子,高度为aia_iai ,我们有qqq次操作.在l到r的范围内砍yyy次,将所有的树高都砍为0,但是保证每一刀砍出来的长度(砍除树高于该高度的和)都是相同的.问你第xxx次砍的时候 ...
- 牛客第十场 F.Popping Balloons
第一维直接遍历 第二维用线段树维护每个最左端可以得到的贡献 在线段树上每次删除一个点会影响到 X X-R X-2*R 3个值 最多操作1e5次 复杂度 6*n*logn(删了还要加回来 #i ...
- 牛客第三场 F Popping Balloons —— 思维 + 搞题
题目链接:点我啊╭(╯^╰)╮ 题目大意: 二维平面,nnn 个气球 要求水平方向射三枪,垂直射三枪 每一枪可以打穿一行或一列的所有气球 水平或垂直的相邻枪的距离为 rrr ...
- 因式分解(2019,牛客 ,7场B)
题目:不可约多项式 链接:https://ac.nowcoder.com/acm/contest/887/B 题意: T组样例,每组一个n,代表多项式的最高次数,n+1个数,代表系数. 输出多项式能不 ...
- 牛客第六场 H-Hopping Rabbit
牛客第六场 H-Hopping Rabbit 给出平面上的n个矩形,一只兔子从(x0+0.5,y0+0.5)(x_0+0.5,y_0+0.5)(x0+0.5,y0+0.5)出发,每一次可以平行于x ...
- 牛客小白月赛61 F.选座椅(双指针)
牛客小白月赛61 F.选座椅(双指针) 显然 ( l , r ) (l,r) (l,r)满足 ( l , r + 1 ) (l,r+1) (l,r+1)满足. 那么可以考虑双指针,枚举 l l l,然 ...
- 牛客小白月赛2 F.黑黑白白
牛客小白月赛2 F.黑黑白白 题目链接 题目描述 艮为山,动静得宜,适可而止:兑为泽,刚内柔外,上下相和. 艮卦:兼山,艮:君子以思不出其位.财帛常打心头走,可惜眼前难到手,不如意时且忍耐,逢着闲事休 ...
- 2019年牛客多校第1场 赛后总结
A题 :Equivalent Prefixes 题意:就是给你两个有n个不同数的串,然后保证1-p区间内任选一个区间,使得区间中最小值的下标相同,找到最大的p值 思路:我的思路是设置两个单调栈,然 ...
- 牛客小白月赛12 F 华华开始学信息学 (分块+树状数组)
链接:https://ac.nowcoder.com/acm/contest/392/F 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 32768K,其他语言65536 ...
最新文章
- android studio 导入库提示失败的处理方法以及androidstudio 清理缓存的方法
- js 多维数组长度_C++申请与释放动态数组1(学习笔记:第6章 16)
- winform配置文件的简单使用(转载)
- python与vb可以互换吗_vb能配合python写程序么?
- python 代理使用方法简介
- 武汉网络推广浅析当网站停止收录时该检查哪些问题?
- 光猫直连电脑不能上网_电脑插上网线不能上网怎么办
- ubuntu14.04 在自带python2.7上安装python3.3.5 可以用但是有问题
- SCOM 常识概念—与其他SC产品集成
- linux aix 环境,在AIX中设置中文环境
- 从C#到Nodejs,从windowns到mac
- 5.10 图上的傅里叶变换和逆变换
- Protel99se基本教程 Protel 99SE从零开始学习教程视频教程
- http://baiy.cn/doc/cpp/inside_exception.htm#栈回退(Stack_Unwind)机制
- python视频字幕处理_用Python处理字幕文件
- 支付宝小程序对接流程和工具类
- 蓝桥杯--第七届决赛:圆圈舞
- 2013年9月19日
- 最大堆和最小堆(数据结构)
- matlab 邦加球,吴先良(软件学院)老师 - 安徽大学