当前位置: 首页 > news >正文

BZOJ2744:[HEOI2012]朋友圈(最大团,乱搞)

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之间“朋友”的情况。
4.在 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行,每行,输出一个整数,表示最大朋友圈的数目。

Sample Input

2 4 7
1 2
2 6 5 4
1 1
1 2
1 3
2 1
2 2
2 3
2 4

Sample Output

5
【样例说明】
最大朋友圈包含A国第1、2人和B国第1、2、3人。

HINT

【数据范围】
两类数据
第一类:|A|<=200 |B| <= 200
第二类:|A| <= 10 |B| <= 3000

Solution

$A$了这个题才发现这个题网上怎么清一色匈牙利……QAQ。来一发应该是对的乱搞做法。

定义权值为奇数的为奇点,偶数的为偶点。首先简单分析一下$A,B$国的性质,可以发现:

$A$国内的边只有奇点连向偶点,也就是说只看$A$国的话是一个奇-偶的完全二分图。且若答案最大团里含$A$国的人,则奇点最多只有一个,偶点最多只有一个。(因为如果选两个奇点的话这两个奇点中间必定没有边,偶点同理。)

$B$国内奇点成一个团,偶点成一个团,且$(b_i~or~b_j)$化成二进制有奇数个$1$的也互连。也就是两个团之间连着几条边的形态。

分析完性质,可以发现$B$国的两个团并不一定是极大团,因为如果两个团之间连着的边足够的话,奇点也是可以被并到偶团里的。那么我们暴力一下,把$B$国的两个团都扩成极大团。

因为$A$国只有可能被选$0,1,2$个点去和$B$国的两个极大团合并,枚举一下$A$国选哪些就好了。

注意一些边界条件,具体看代码。

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 #define N (3009)
 6 using namespace std;
 7 
 8 int n,m,x,y,u,v,ans;
 9 int a[N],b[N],G[N][N];
10 vector<int>A[2],B[2];
11 
12 inline int read()
13 {
14     int x=0,w=1; char c=getchar();
15     while (!isdigit(c)) {if (c=='-') w=-1; c=getchar();}
16     while (isdigit(c)) x=x*10+c-'0', c=getchar();
17     return x*w;
18 }
19 
20 int bitcount(int x)
21 {
22     return x?bitcount(x>>1)+(x&1):0;
23 }
24 
25 bool check(int x,int opt)
26 {
27     bool flag=1;
28     for (int i=0; i<B[opt].size(); ++i)
29         if (!G[x][B[opt][i]]) flag=0;
30     return flag;
31 }
32 
33 int main()
34 {
35     x=read(); y=read(); m=read(); n=x+y;
36     for (int i=1; i<=x; ++i) A[(a[i]=read())%2].push_back(i);
37     for (int i=1; i<=y; ++i) B[(b[i]=read())%2].push_back(i);
38     for (int i=1; i<=m; ++i) G[u=read()][v=read()]=G[v][u]=1;
39     
40     for (int i=1; i<=y; ++i)
41     {
42         int t=b[i]%2, flag=1;
43         for (int j=0; j<B[t^1].size(); ++j)
44         {
45             int tmp=b[B[t^1][j]];
46             if (tmp%2==(t^1) && bitcount(b[i]|tmp)%2==0) flag=0;
47         }
48         if (flag) B[t^1].push_back(i);
49     }
50     
51     ans=max((int)B[0].size(),(int)B[1].size());//只选B国的极大团之一。 
52     ans=max(ans,(bool)A[0].size()+(bool)A[1].size());//只选A国。 
53     for (int i=0; i<A[0].size(); ++i)//有一种特殊情况,为A国两个点加B国一个点的团。
54         for (int j=0; j<A[1].size(); ++j)
55             for (int k=1; k<=y; ++k)
56                 if (G[A[0][i]][k] && G[A[1][j]][k]) ans=max(ans,3);
57                 
58     for (int i=0; i<A[0].size(); ++i)//选一个A国偶点。 
59     {
60          if (check(A[0][i],0)) ans=max(ans,(int)B[0].size()+1);
61          if (check(A[0][i],1)) ans=max(ans,(int)B[1].size());
62     }
63     for (int i=0; i<A[1].size(); ++i)//选一个A国奇点。 
64     {
65         if (check(A[1][i],0)) ans=max(ans,(int)B[0].size()+1);
66         if (check(A[1][i],1)) ans=max(ans,(int)B[1].size()+1);
67     }
68     for (int i=0; i<A[0].size(); ++i)//选一个A国偶点和一个A国奇点。 
69         for (int j=0; j<A[1].size(); ++j)
70         {
71             if (check(A[0][i],0) && check(A[1][j],0)) ans=max(ans,(int)B[0].size()+2);
72             if (check(A[0][i],1) && check(A[1][j],1)) ans=max(ans,(int)B[1].size()+2);
73         }
74     printf("%d\n",ans);
75 }

转载于:https://www.cnblogs.com/refun/p/10438009.html

相关文章:

  • 突破自己的技术思维
  • Javascript编码规范
  • 软件开发学习的5大技巧,你知道吗?
  • Linux快速复制或删除大量小文件
  • c#用winform开发一个简易双色球项目
  • 微信小程序设置上一页数据
  • Java教程_软件开发基础
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • spring cloud构建互联网分布式微服务云平台-消息总线
  • Android之Window与WindowManager
  • Linux 抓包工具 tcpdump
  • Linux CTF 逆向入门
  • Choerodon 猪齿鱼 0.14 发布,开源企业级数字化服务平台
  • 网络应用优化——时延与带宽
  • 「面试题」如何实现一个圣杯布局?
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 345-反转字符串中的元音字母
  • iOS 系统授权开发
  • mockjs让前端开发独立于后端
  • Vue实战(四)登录/注册页的实现
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 简单实现一个textarea自适应高度
  • 经典排序算法及其 Java 实现
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 回归生活:清理微信公众号
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #git 撤消对文件的更改
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (初研) Sentence-embedding fine-tune notebook
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)项目管理杂谈-我所期望的新人
  • .net 简单实现MD5
  • .net打印*三角形
  • .NET中的Exception处理(C#)
  • .net中的Queue和Stack
  • .Net转前端开发-启航篇,如何定制博客园主题
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [AIGC] 开源流程引擎哪个好,如何选型?
  • [android] 请求码和结果码的作用
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [CSS]盒子模型
  • [EFI]英特尔 冥王峡谷 NUC8i7HVK 电脑 Hackintosh 黑苹果efi引导文件
  • [Go WebSocket] 多房间的聊天室(三)自动清理无人房间
  • [IE编程] 如何编程清除IE缓存
  • [Python从零到壹] 五十三.图像增强及运算篇之直方图均衡化处理