您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: