您的位置:首页 > 其它

poj 2771 Guardian of Decency (二分图求最大独立集)

2014-03-25 20:41 323 查看
Sample Input
2
4
35 M classicism programming
0 M baroque skiing
43 M baroque chess
30 F baroque soccer
8
27 M romance programming
194 F baroque programming
67 M baroque ping-pong
51 M classicism programming
80 M classicism Paintball
35 M baroque ping-pong
39 F romance ping-pong
110 M romance Paintball

Sample Output
3
7

Source

题意:现在有一个老师想带领他的学生出去郊游,但是他非常担心在郊游的过程中有些学生会发生恋爱关系,而他认为发生恋爱关系的可能性比较小的判断标准有以下四个,如果满足四个条件中的任何一个,即被他认为可能发生恋爱关系的可能性比较小:

1>两人身高的差距超过40cm;

2>两人性别相同;

3>两人所喜欢的音乐风格不同;

4>两人最喜爱的运动相同;

现在给出n个学生,并给出每个学生的信息(信息为:身高 性别 所喜欢的音乐风格 喜爱的运动),要求求解最大可以带出去郊游的学生数.

将所有可以发生恋爱关系的男女进行配对,即将男同学和女同学做为两个顶点集合,如果某一对男女同学能发生恋爱关系,就将二者连接,从而建立二分图,那么可以带的出去的人数应该等于这个二分图的最大独立集.

最大独立集:最大的一个集合,其中的每两点之间都不存在边.

最大独立集=顶点数-最大匹配数.

#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<stack>
#include<queue>
#include <iomanip>
#include<iostream>
#include<algorithm>
using namespace std ;
const int N=550;
map<string,int>m,s ;
struct node
{
	int sport , music ;
	int high;
}g
,b
;
int match
,vist
;
int M

 ;
int gn,bn;	

int dfs(int i)
{
	 for(int  j = 0 ; j < gn ; j++)
	 {
	 	   if(!vist[j] && M[i][j])
	 	   {
	 	   	   vist[j]=1;
	 	   	   if(match[j]==-1 || dfs(match[j]))
	 	   	   {
	 	   	   	        match[j]=i;   
	 	   	   	        return 1;
	 	   	   }
	 	   } 	
    }
	return 0;
}	
	
int main()
{
	int music_cnt,sport_cnt , k , n;
	scanf("%d",&k);
	while(k--)
	{
		 memset(M,0,sizeof(M));
	     string music,sport ;
		 char  sex ;
		 int high;
		  gn=0,bn=0;
		 music_cnt=sport_cnt=1;
		 m.clear();
		 s.clear();
		 scanf("%d",&n);
		 for(int i = 1 ; i <= n ; i++)
		 {
		 	    cin>>high>>sex>>music>>sport;
		 	    if(sex=='M')                           //男生 
		 	    {
		 	    	 b[bn].high=high;
		 	    	 if(m[music]==0) m[music]=music_cnt++ ; //第music_cnt种音乐 
		 	    	 if(s[sport]==0) s[sport]=sport_cnt++;
		 	    	 b[bn].music=m[music];
		 	    	 b[bn++].sport=s[sport];
		 	    }
		 	    else 
		 	    {
		 	    	g[gn].high=high;
		 	    	 if(m[music]==0) m[music]=music_cnt++ ;
		 	    	 if(s[sport]==0) s[sport]=sport_cnt++;
		 	    	 g[gn].music=m[music];
		 	    	 g[gn++].sport=s[sport];
		 	    }
		 } 
		 for(int i = 0 ; i < bn ; i++)
		   for(int j = 0 ; j < gn ; j++)
		     {                                     //可能恋爱的 男女连边 
		     	   if(abs(b[i].high-g[j].high)<=40 && b[i].music==g[j].music && b[i].sport!=g[j].sport ) 
		     	         M[i][j]=1;
		     	
		     }
	     memset(match,-1,sizeof(match));
	     int ans = 0 ;
	     for(int i = 0 ; i < bn ; i++)   //男生配女生 
	     {
	     	  memset(vist,0,sizeof(vist));
			   ans += dfs(i) ; 
	     }
	     printf("%d\n",n-ans);
	
	} 
	  return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: