BZOJ 2744 浅谈异或二进制分析及二分图最大团
来源:互联网 发布:淘宝开店模板 编辑:程序博客网 时间:2024/06/14 19:59
世界真的很大
今天考试的第三题
发现了点性质但是时间复杂度分析不能过
实在是没有什么思路了写了个暴力
寄希望于评测机跑的快一点没想到居然是正解
看题先:
description:
在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着。一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目。
两个国家看成是AB两国,现在是两个国家的描述:
1. A国:每个人都有一个友善值,当两个A国人的友善值a、b,如果a xor b mod 2=1,
那么这两个人都是朋友,否则不是;
2. B国:每个人都有一个友善值,当两个B国人的友善值a、b,如果a xor b mod 2=0
或者 (a or b)化成二进制有奇数个1,那么两个人是朋友,否则不是朋友;
3. A、B两国之间的人也有可能是朋友,数据中将会给出A、B之间“朋友”的情况。
- 在AB两国,朋友圈的定义:一个朋友圈集合S,满足
S∈A∪ B ,对于所有的i,j∈ S ,i 和 j 是朋友
由于落后的古代,没有电脑这个也就成了每年最大的难题,而你能帮他们求出最大朋 友圈的人数吗?
input:
第一行t<=6,表示输入数据总数。
接下来t个数据:
第一行输入三个整数A,B,M,表示A国人数、B国人数、AB两国之间是朋友的对数;第二行A个数ai,表示A国第i个人的友善值;第三行B个数bi,表示B国第j个人的友善值;
第4——3+M行,每行两个整数(i,j),表示第i个A国人和第j个B国人是朋友。
output:
输出t行,每行,输出一个整数,表示最大朋友圈的数目。
当时做的时候,一看要求就是要求一个最大团
一般的图求最大团是指数级的肯定不可能
那么最大团可以接受的算法就是二分图的最大团了,nm的
考虑二分图的最大团的条件,即两个集合,每个集合的元素之间互相两两有边,然后两个集合互相有边,跑最大团
但是把这两个集合当成A和B来做的话显然不太合适,因为首先就没有满足A集合或者B集合两两有边的条件
但是这道题的建边方式不一般,肯定有什么门道
观察发现A中元素的朋友的条件是友善值一奇一偶,灵光一现A最多两个人
那我们就枚举哪两个人,然后把他们相交的部分在B集合里面选出来然后搞一个最大团
但是这个最大团的复杂度严格来说和直接求是一致的,那还是要往二分图上想
考虑B里面是朋友的方式
然后想到只要都是奇数,或者都是偶数,互相之间肯定是有边的
那么就完全转化成二分图的模型了
用补图的最大点独立集就好
最好不要每次memset,搞一个时间戳什么的比较好
注意这道题的输入里面有重边,所以判断每次B里面选了几个的时候需要略略注意一下
完整代码:
#include<stdio.h>#include<cstring>#include<vector>using namespace std;struct edge{ int v,last;}ed[9000010];vector <int> va[3010];int n,m,Q,num=0,tot=0,idx=0,T,vnt=0;int head[3010],mrk[3010],vis[3010];int a[3010],b[3010],match[3010],book[3010];void add(int u,int v){ num++; ed[num].v=v; ed[num].last=head[u]; head[u]=num;}int dfs(int u){ for(int i=head[u];i;i=ed[i].last) { int v=ed[i].v; if(mrk[v]==vnt && book[v]!=tot) { book[v]=tot; if(!match[v] || dfs(match[v])) { match[u]=v,match[v]=u; return 1; } } } return 0;}bool check(int i,int j){ int x=b[i] | b[j],cnt=0; while(x) { if(x&1) cnt++; x>>=1; } if(cnt&1) return false ; return true ;}void Build(){ for(int i=1;i<=m;i++) if(b[i]&1) for(int j=1;j<=m;j++) if(b[j]%2==0) if(check(i,j)) add(i,j); }int CAL(){ int ans=0; tot=0; memset(match,0,sizeof(match)); for(int i=1;i<=m;i++) if((b[i]&1) && mrk[i]==vnt) { tot++; if(!match[i]) ans+=dfs(i); } return idx-ans;}int main(){ scanf("%d%d%d",&n,&m,&Q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) scanf("%d",&b[i]); while(Q--) { int u,v; scanf("%d%d",&u,&v); va[u].push_back(v); } Build(); int ans=0; vnt++; for(int i=1;i<=m;i++) mrk[i]=vnt; idx=m; ans=max(ans,CAL()); for(int i=1;i<=1;i++) { idx=0,vnt++; for(int j=0;j<va[i].size();j++) mrk[va[i][j]]=vnt; for(int j=1;j<=m;j++) if(mrk[j]==vnt) idx++; ans=max(ans,CAL()+1); } for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if((a[i]^a[j])%2==1) { idx=0,vnt++; for(int k=0;k<va[i].size();k++) vis[va[i][k]]=vnt; for(int k=0;k<va[j].size();k++) if(vis[va[j][k]]==vnt) mrk[va[j][k]]=vnt,idx++; ans=max(ans,CAL()+2); } printf("%d\n",ans); return 0;}/*EL PSY CONGROO*/
嗯,就是这样
- BZOJ 2744 浅谈异或二进制分析及二分图最大团
- bzoj 2744: [HEOI2012]朋友圈 (二分图最大团)
- 二分图最大团-poj3692
- poj3692二分图最大团
- 最大团&&二分图2
- 图论 二分图 最大团
- bzoj2744 二分图 最大团
- [最大团 随机化 || 二分图最大独立集] BZOJ 4080 [Wf2014]Sensor Network
- BZOJ 2744 朋友圈 (最大团)
- bzoj 2744: [HEOI2012]朋友圈 最大团
- poj3692 补图二分图,最大团
- Poj 3692 二分图最大团
- poj 3692 (二分图最大团)
- poj3692----图论---二分图最大团
- poj3692 二分图的最大团
- POJ 3692 Kindergarten (二分图 最大团)
- HDU3585-二分+最大团
- poj 3692(浅谈二分图最大匹配求最大独立集在解决最大团问题中的应用)
- 菜鸟学数据库(四)——超键、候选键、主键、外键
- 洛谷P1979 华容道(dfs)
- python基础-打开模式、seek、修改文件、with上下文管理、truncate
- Redis keys 命令
- 红黑树(RB-tree)比AVL树的优势在哪?
- BZOJ 2744 浅谈异或二进制分析及二分图最大团
- array_diff 数组差集
- SSM整合的一些配置(基于Maven工程,逆向工程,Restful风格)
- leetcode解题方案--024--Swap Nodes in Pairs
- Struts2_012_Struts中文处理
- PageHelper5.0.0分页插件与mybatis的集成
- spring httpMessageConverter 和 @ResponseBody
- 页面布局 --- 两列均分布局
- 基于Bmob,环信easeUI的校园二手交易市场——用户管理(含头像),数据管理,文件管理(图片管理),聊天功能的开发