poj 2771 二分匹配 Guardian of Decency

http://poj.org/problem?id=2771

一个保守的老师带学生出去玩,他希望任何一人不能配成一对,问你K个人中他能带出去的最大人数

 

最大独立集= 顶点数(总人数) - 最大匹配数     

因为最小点覆盖集==最大匹配数

最小点覆盖集: 假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。

因此最大独立集 = 顶点数  -  最小点覆盖集

http://www.matrix67.com/blog/archives/116证明由matrix67给出

  

代码(⊙o⊙)
#include"stdio.h"
#include
"string.h"

bool map[501][501];
int mark[501];
bool flag[501];
int k,g,m;//g女的,m男的数量

struct
{
int tall;
char sex;
char music[105],sport[105] ;
} boy[
505],girl[505];

void get_map()
{
int i,x,y,j;
int flag1;
g
=m=0;
int tall1;
char sex1,str1[105],str2[105];
getchar();
for(i=0;i<k;i++)
{
scanf(
"%d %c %s%s",&tall1,&sex1,str1,str2 ) ;

if( sex1=='F')
{
girl[
++g ].tall = tall1;
girl[ g ].sex
=sex1;
strcpy( girl[g].music ,str1 );
strcpy( girl[g].sport ,str2 );
}
else
{
boy[
++m ].tall = tall1;
boy[ m ].sex
=sex1;
strcpy( boy[m].music ,str1 );
strcpy( boy[m].sport ,str2 );
}
}

for(i=1;i<=g;i++)
for(j=1;j<=m;j++)
{
flag1
=1;
if( girl[i].tall - boy[j].tall >40 || girl[i].tall - boy[j].tall < -40 )
flag1
=0;

if( strcmp( girl[i].music ,boy[j].music ) !=0 )
flag1
=0;

if( strcmp( girl[i].sport , boy[j].sport )==0 )
flag1
=0;

if( flag1 )
map[i][j]
=1;
}




}

bool dfs(int x)
{
int i;
for(i=1;i<=m;i++)
{
if(!map[x][i]||flag[i])
continue;
flag[i]
=1;
if(!mark[i]||dfs(mark[i]))//i点为孤立点,或者i不是孤立点时寻找i所对应的女生的增广路,如果那个女生能找到另一条增广路径
{
mark[i]
=x; //就可以使i变成孤立点,从而使增广路径的长度加1,此处的dfs(mark[i])就是找i对应的女生能否有另
return 1; //一条不包含i的增广路径,而mark[]是用来判断是否是孤立点的。
}

}
return 0;
}

void solve()
{
int i,count=0;
memset(mark,
0,sizeof(mark));//记录女孩i对应的男孩//
for(i=1;i<=g;i++)
{
memset(flag,
0,sizeof(flag));//标记是否被访问过//
if(dfs(i))
{
count
++;
}
}
printf(
"%d\n",k-count);
}


int main()
{
int t;
scanf(
"%d",&t);
while( t-- && scanf("%d",&k)!=EOF )
{

memset(map,
0,sizeof(map));
get_map();
solve();
}
return 0;
}

 

posted on 2011-01-18 16:17  翱翔九天  阅读(251)  评论(0编辑  收藏  举报