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[N],b[N];
int match[N],vist[N];
int M[N][N] ;
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;
}