poj 3692 最大团(二分图匹配,最大独立集)
2016-04-18 15:11
387 查看
http://poj.org/problem?id=3692
题意:
每个男生之间都相互认识,每个女生之间都相互认识,每个男生可能认识部分女生。求一个集合里面的人相互都认识,这个集合的人数最多是多少。
思路:
相互都认识,如果把认识关系当做边的话,那么要求的就是最大完全子图(也叫最大团)。
可以发现男生和女生自身都是一个完全子图,所以按照认识关系建图的话,违背了二分图的原则。思考用不认识的关系建边,就转换成求一个最大独立集所包含的点数。
其实本身也就有这个定理:
最大团=原图补图的最大独立集
题意:
每个男生之间都相互认识,每个女生之间都相互认识,每个男生可能认识部分女生。求一个集合里面的人相互都认识,这个集合的人数最多是多少。
思路:
相互都认识,如果把认识关系当做边的话,那么要求的就是最大完全子图(也叫最大团)。
可以发现男生和女生自身都是一个完全子图,所以按照认识关系建图的话,违背了二分图的原则。思考用不认识的关系建边,就转换成求一个最大独立集所包含的点数。
其实本身也就有这个定理:
最大团=原图补图的最大独立集
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define M 1009 int mp[M][M]; int g,b,m; bool used[M]; int match[M]; void init() { for(int i = 1;i <= g;i++) { for(int j = 1;j <= b;j++) mp[i][j] = 1; } //memset(mp,0,sizeof(mp)); } bool dfs(int u) { for(int i = 1; i <= b;i++) { if(mp[u][i] == 0) continue; int v = i; if(!used[v]) { used[v] = true; if(match[v] == -1 || dfs(match[v])) { match[v] = u; return true; } } } return false; } int b_match() { int ans = 0; memset(match,-1,sizeof(match)); for(int i = 1;i <= g;i++) { memset(used,false,sizeof(used)); if(dfs(i)) ans++; } return ans; } int main() { int k = 0; while(scanf("%d %d %d",&g,&b,&m) == 3) { k++; init(); if(g == 0 && b == 0 && m == 0) break; for(int i = 0; i < m;i++) { int u,v; scanf("%d %d",&u,&v); mp[u][v] = 0; } printf("Case %d: ",k); int ans = b_match(); printf("%d\n",g+b-ans); } return 0; }
相关文章推荐
- HDU2084 数塔 DP水题
- 创业之路不止互联网一条
- Git 常用命令整理
- 图片
- Android SurfaceView使用详解
- Android基础--EditText输入框限制小数的位数解决方法
- 在配置hadoop的时候碰到的问题
- python 字符编码出现的问题 IDLE 一定要设置啊!!!!!!!
- spm使用之六安装别人写好的spm文档主题模板
- 神经网络学习笔记-问题记录(三)
- 团队作业2
- openStack Packages yum upgrade
- createrepo -g /enp/comps.xml .
- hbase内存分配那些事
- 加载,渲染,绘制
- 剑指offer之面试题9-4:矩形覆盖
- spm使用之五修改spm自带文档主题模板
- seajs配合spm应用之四弹出框
- HTML5之Range对象
- html列表、块