题目大意:

有\(A,B\)两个点集,每个点有点权,在\(A\)集合中,两个点之间有边满足\(a_i\ xor\ a_j\ mod\ 2 = 1\),在\(B\)集合中,两个点之间有边满足\(b_i\ xor\ b_j\ mod\ 2=0\)或者\(b_i\ or\ b_j\)化成二进制有奇数个\(1\)

求\(A,B\)集合的最大团的大小

第一类数据:\(|A|\le 200,|B|\le 200\)

第二类数据:\(|A|\le 10,|B|\le 3000\)

目前算法表示最大团问题是个\(NPC\)问题,所以我们不能直接解决

但是我们也许知道,最大团=补图最大独立集

考虑建立补图求最大独立集

对于\(A\)集合,在原图中奇偶不同的点之间有边,则在补图中奇偶相同的点之间全部有边,奇偶不同的点之间没有边,对于补图最大独立集,\(A\)图中最多选两个

对于\(B\)集合,在原图中奇偶相同的点之间有边,奇偶不同的点一些有边,则在补图中,奇偶相同的点之间没有边,我们可以以奇偶为划分标准将补图划分成二分图

建出补图后,因为\(A\)集合中点数很少,我们可以枚举\(A\)集合中选取的点,然后把与这些点构成完全图的\(B\)集合中的点标记,跑二分图最大独立集

略卡常,加时间戳优化

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
namespace red{
#define eps (1e-8)
inline int read()
{
int x=0;char ch,f=1;
for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
if(ch=='-') f=0,ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
}
const int N=3010;
int haku;
int n,m,k,ret,tim,tim2;
int T[N];
int ap[N],bp[N];
bool jx[N][N];
bool jxb[N][N];
int vis[N<<2],f[N<<2];
int t3[N<<2];
int py[N],num;
int ans;
int head[N],cnt;
struct point
{
int nxt,to;
point(){}
point(const int &nxt,const int &to):nxt(nxt),to(to){}
}a[N*N];
inline void link(int x,int y)
{
a[++cnt]=(point){head[x],y};head[x]=cnt;
}
inline bool check(int x)
{
int sum=0;
for(;x;x-=(x&-x)) ++sum;
return sum&1;
}
inline bool find(int x)
{
for(int i=head[x];i;i=a[i].nxt)
{
int t=a[i].to;
if(vis[t]!=tim&&T[t]==tim2)
{
vis[t]=tim;
if(t3[t]!=tim||!f[t]||find(f[t]))
{
f[t]=x;
t3[t]=tim;
return 1;
}
}
}
return 0;
}
inline int solve()
{
int ret=0;
for(int i=1;i<=m;++i)
{
if(T[i]==tim2) ++tim,ret+=find(i);
else ++ret;
}
return m-ret;
}
inline void main()
{
haku=read();
while(haku--)
{
n=read(),m=read(),k=read();
for(int i=1;i<=n;++i) ap[i]=read();
for(int j=1;j<=m;++j) bp[j]=read();
for(int x,y,i=1;i<=k;++i)
{
x=read(),y=read();
jx[x][y]=1;
}
for(int i=1;i<=m;++i)
{
if(bp[i]&1)
{
for(int j=1;j<=m;++j)
{
if(!(bp[j]&1))
if(!check(bp[i]|bp[j])) link(i,j);
}
}
}
ret=max(ret,solve());
for(int i=1;i<=n;++i)
{
++tim2;
for(int j=1;j<=m;++j)
{
if(jx[i][j]) T[j]=tim2;
}
ret=max(ret,solve()+1);
}
for(int i=1;i<=n;++i)
{
if(ap[i]&1)
for(int j=i+1;j<=n;++j)
{
if(!(ap[j]&1))
{
++tim2;
for(int k=1;k<=m;++k)
{
if(jx[i][k]&&jx[j][k]) T[k]=tim2;
}
ret=max(ret,solve()+2);
} }
}
printf("%d\n",ret);
}
}
}
signed main()
{
red::main();
return 0;
}

洛谷P2423 [HEOI2012]朋友圈的更多相关文章

  1. luogu P2423 [HEOI2012]朋友圈 (最大团)

    在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着. 一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目.两个国家看成是 ...

  2. bzoj 2744: [HEOI2012]朋友圈 二分图匹配

    2744: [HEOI2012]朋友圈 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 612  Solved: 174[Submit][Status] ...

  3. 【BZOJ 2744】 2744: [HEOI2012]朋友圈 (最大团,二分图匹配,构图)

    2744: [HEOI2012]朋友圈 Description 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他 ...

  4. 【二分图】HEOI2012 朋友圈

    题目内容 洛谷链接 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着. 一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大 ...

  5. 洛谷 P1851 好朋友

    题目背景 小可可和所有其他同学的手腕上都戴有一个射频识别序列号码牌,这样老师就可以方便的计算出他们的人数.很多同学都有一个“好朋友” .如果 A 的序列号的约数之和恰好等于B 的序列号,那么 A的好朋 ...

  6. 【BZOJ 2744 】[HEOI2012]朋友圈

    Description 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最 ...

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

    Description 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最 ...

  8. 【刷题】BZOJ 2744 [HEOI2012]朋友圈

    Description 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最 ...

  9. [HEOI2012]朋友圈

    题目 我们发现我们要求的是一个最大团问题,众所周知这是一个\(NP\)难问题,除了爆搜没有什么别的方法,但是这道题我们可以根据图的特殊性质入手 我们如果把\(B\)国的人分成奇数和偶数两类,就会发现奇 ...

随机推荐

  1. springboot做邮件发送功能时报错No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available:的问题解决方案

    1.检查application.yml中的配置是否正确 spring.mail.host=smtp.xxx.comspring.mail.username=xxx@xxx.comspring.mail ...

  2. php 序列化和反序列化的作用及使用

    1.序列化是什么意思呢? 序列化就是把本来不能直接存储的数据转换成可存储的数据,并且不会丢掉数据格式 serialize(); 2.反序列化是什么意思呢? 其实就是字面的意思,把序列化的数据,转换成我 ...

  3. day02-多任务(进程和协程)

    一.多任务的概念       简单地说,就是操作系统可以同时运行多个任务.打个比方,你一边在用浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务,至少同时有3个任务正在运行.还有很多任务 ...

  4. kali Linux的 安装详细步骤

    一.打开"kali 官方网站,下载kali镜像文件.地址(https://www.kali.org/downloads/)   在Download菜单界面下,有历史版本下载和最新版下载.找到 ...

  5. FL Studio20效果器Fruity Reverb 2功能介绍

    FL Studio,也就是我梦通常所说的水果音乐制作软件,是一款新手就可以用的软件.其操作简单,界面简洁大方,就算只用鼠标也可以轻松编曲. FL Studio20中有许多自带合成器是很好用的,同时也是 ...

  6. Tuxera Disk Manager轻松解决硬盘格式转换问题

    生活中经常会遇到硬盘格式转换的问题,很多小伙伴都不知道怎么进行操作,特别是Mac小白们.今天,小编想要给不熟悉Mac系统的小伙伴推荐一款专业且高效的磁盘管理工具--Tuxera NTFS,可以帮助我们 ...

  7. [C#.NET 拾遗补漏]13:动态构建LINQ查询表达式

    最近工作中遇到一个这样的需求:在某个列表查询功能中,可以选择某个数字列(如商品单价.当天销售额.当月销售额等),再选择 小于或等于 和 大于或等于 ,再填写一个待比较的数值,对数据进行查询过滤. 如果 ...

  8. docker中启动容器提示端口被占用

    docker中启动容器提示端口被占用,但是 docker ps -a 查不到信息 1.查询端口被占用的id netstat -ntpl |grep 3306 2.杀掉该id kill -9 如果kil ...

  9. Springboot整合WebSocket实现网页版聊天,快来围观!

  10. [Android systrace系列] 抓取开机过程systrace

    ------------------------------------------------------------------------- 这篇文章的小目标:了解抓取开机过程systrace的 ...