http://poj.org/problem?id=3692
题目大意:有一群男孩,他们互相认识,有一群女孩,她们也互相认识,这些男孩中有以些认识女孩中的某些人,现在找出一群孩子使得他们都认识,并且数目最多。
有题目给定的条件,可以很容易的将其判定为二分图的匹配,但是要从其中找出都互相认识的,并且使得数目最大,比较困难,我们可以逆向思考,找出一个集合使得其中的人数最多,并且集合中的所有人都不认识,这就是最大独立集,这样我们就可以用找出二分图匹配数,然后用总的人数减去匹配数,就是对应的熟悉的人群,并且数目最大。
代码如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std ;
const int maxn = 205 ;
int boy[maxn] ;
int girl[maxn] ;
int map[maxn][maxn] ;
int mk[maxn] ;
int dfs(int v) ;
int maxmatch() ;
int m ;
int n ;
int p ;
int test ;
int main()
{
test = 0 ;
while(scanf("%d%d%d" , &m , &n , &p)!=EOF && (m||n||p))
{
int i ;
int j ;
int x ;
int y ;
memset(map , 0 , sizeof(map)) ;
for(i = 0 ; i < p ; i ++)
{
scanf("%d%d", &x , &y) ;
map[x][y] = 1 ;
}
x = maxmatch();
printf("Case %d: %d\n" , ++test , n + m - x) ;
}
return 0 ;
}
int maxmatch()
{
int res = 0 ;
memset(boy , -1 , sizeof(boy)) ;
memset(girl , -1 , sizeof(girl)) ;
for(int i = 1 ; i <= m ; i ++)
{
if(girl[i]==-1)
{
memset(mk , 0 , sizeof(mk)) ;
res += dfs(i) ;
}
}
return res ;
}
int dfs(int v)
{
int u ;
for(u = 1 ; u <= n ; u ++)
{
if(map[v][u]==0 && !mk[u])
{
mk[u] = 1 ;
if(boy[u]==-1 || dfs(boy[u]))
{
boy[u] = v ;
girl[v] = u ;
return 1 ;
}
}
}
return 0 ;
}