题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2744

首先,求一个图的最大团等价于求它的补图的最大独立集,而二分图的最大独立集 = 总点数 - 最大匹配数;

所以先把图转化成补图,也就是A国奇、偶点各自成团,B国奇、偶点相互连边而其内部无边,还有些A到B的边用邻接矩阵存了;

可以发现A国最多只能选出两个点来,而A国选的那些点会影响B国的最大独立集;

发现A国点很少,不妨暴力枚举!

注意计算最大独立集时减去的数 tmp,原来写的是 tmp = 最大匹配数,其中左部点(B国奇数点)不管,右部点和A国点相连的也匹配;

想的是右部点中和A国相连的就算匹配上了也会算在减去的部分,但这样不太对呢,而且会少算左部点中和A国相连的;

所以直接再来一个 out 数组表示和A国点相连,把B国中左右部的 out 点都算上,然后匹配时不去匹配 out 的右部点;

虽然感觉挺麻烦但其实也挺好写的。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int const maxn=;
int A,B,m,a[],b[maxn],pre[maxn],ans,tmp,sid[][maxn];
bool vis[maxn],out[maxn];
vector<int>vb[maxn];
bool dfs(int x)
{
for(int i=;i<vb[x].size();i++)
{
int u=vb[x][i];
if(vis[u]||out[u])continue; vis[u]=;
if(!pre[u]||dfs(pre[u])){pre[u]=x;return ;}
}
return ;
}
bool ck(int x,int y)
{
int k=(x|y),ret=;
for(;k;k-=(k&-k))ret++;
return (ret&);
}
int main()
{
scanf("%d%d%d",&A,&B,&m);
for(int i=;i<=A;i++)
{
scanf("%d",&a[i]);
// if(a[i]&1)a1.push_back(i);
// else a2.push_back(i);
}
for(int i=;i<=B;i++)
{
scanf("%d",&b[i]);
for(int j=;j<i;j++)
{
if(ck(b[i],b[j])||(b[i]^b[j])%==)continue;//补图上无边
vb[i].push_back(j),vb[j].push_back(i);
}
}
for(int i=,x,y;i<=m;i++){scanf("%d%d",&x,&y); sid[x][y]=;}
for(int j=;j<=B;j++)
{
if(b[j]%==)continue;//不dfs右部点
memset(vis,,sizeof vis);
if(dfs(j))ans++;
}
ans=B-ans;
for(int i=;i<=A;i++)
{
tmp=;
memset(pre,,sizeof pre);
memset(out,,sizeof out);
for(int j=;j<=B;j++)if(!sid[i][j])out[j]=,tmp++;//补图上有边
for(int j=;j<=B;j++)
{
if(b[j]%==||out[j])continue;
// if(!sid[i][j]){tmp++; continue;}
memset(vis,,sizeof vis);
if(dfs(j))tmp++;
}
tmp=B-tmp+;
ans=max(ans,tmp);
}
for(int i=;i<=A;i++)
{
// int i=a1[ii];
if(a[i]%==)continue;
for(int j=;j<=A;j++)
{
if(a[j]%==)continue;
// int j=a2[jj];
tmp=;
memset(pre,,sizeof pre);
memset(out,,sizeof out);
for(int k=;k<=B;k++)if(!sid[i][j]||!sid[j][k])out[j]=,tmp++;//!
for(int k=;k<=B;k++)
{
if(b[k]%==||out[k])continue;//补图上有边
memset(vis,,sizeof vis);
if(dfs(k))tmp++;
}
tmp=B-tmp+;
ans=max(ans,tmp);
}
}
printf("%d\n",ans);
return ;
}

bzoj2744 [HEOI2012]朋友圈——二分图匹配的更多相关文章

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

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

  2. BZOJ2744 HEOI2012朋友圈(二分图匹配)

    先考虑B国.容易发现a xor b mod 2=0即二进制末位相同,那么可以据此将所有人分成两部分,每一部分各自是一个完全图.然后再将a or b有奇数个1的边连上,现在需要求的就是这样一个图里的最大 ...

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

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

  4. BZOJ2744: [HEOI2012]朋友圈

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2744 最大团是一个np问题.. 对于本题,做它的逆问题,建反图做最大独立集. 对于A最多取出两 ...

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

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

  6. 【二分图】HEOI2012 朋友圈

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

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

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

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

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

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

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

随机推荐

  1. vue+webpack+npm搭建的纯前端项目

    转载来源:https://www.cnblogs.com/shenyf/p/8341641.html 搭建node环境 下载 1.进入node.js官方网站下载页,点击下图中框出位置,进行下载即可,当 ...

  2. 如何做到在webpack打包vue项目后,在外部动态修改配置文件

    在我们做完vue项目后,只需要执行 npm run dist 就可以轻松进行打包转测试,可是如果我们临时需要修改一些配置文件比如域名,这时候我们就有点懵逼了,那就修改了再重新打一次包? NO NO N ...

  3. Luogu P3110 [USACO14DEC]驮运Piggy Back

    解题思路 看到下面很多人都在说什么遇到了之后要不要背着走,其实根本不需要,同样的我也是跑了三遍$SPFA$,求出了以$1$为起点到个点的$dist$,和以$2$为起点到个点的$dist$,还有以$n$ ...

  4. [Luogu] P4254 [JSOI2008]Blue Mary开公司

    题目背景 Blue Mary 最近在筹备开一家自己的网络公司.由于他缺乏经济头脑,所以先后聘请了若干个金融顾问为他设计经营方案. 题目描述 万事开头难,经营公司更是如此.开始的收益往往是很低的,不过随 ...

  5. Linux设置history命令显示行数以及时间

    Linux和unix上都提供了history命令,可以查询以前执行的命令历史记录但是,这个记录并不包含时间项目因此只能看到命令,但是不知道什么时间执行的如何让history记录时间呢? 解决方案 注意 ...

  6. Struts2学习笔记:DMI,多个配置文件,默认Action,后缀

    动态方法调用有三种方法: 1.同一Action多次映射,每个action标签的method对应要调用的方法. 当要调用的方法多了就会增加struts.xml文件的复杂性. 2.struts.Dynam ...

  7. npm安装node包时怎么显示安装进度

    npm config set loglevel=http 打开这个你会看到所有的 HTTP 请求,除此之外如果还有 \ 长时间打转,那就是外部模块的编译过程,一个字:等. 具体地址可参考https:/ ...

  8. nyoj 4 ASCII码排序(set,multiset)

    ASCII码排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符.   输入 第一行输 ...

  9. 个人常用git命令

    最近开始使用git,将自己常用git命令做一个简单归纳,便于记忆. 初始化及配置 git init:初始化资料库 git config --global user.name 'xxx':配置用户名 g ...

  10. SGU - 321 - The Spy Network

    先上题目: 321. The Spy Network Time limit per test: 0.5 second(s)Memory limit: 65536 kilobytes input: st ...