/**
解题思路:将每个学生当做一个结点,如果两个人4个条件都不满足,就意味着他们不能同时被选择,连一条无向边。问题就转化为求这个图的最大独立集。可以分男女入图,也可以不分男女。下面给出两种方法。
*/
题目大意:
有个思想保守的老师的老师,组织外出,但又怕同学在旅途中产生爱意,于是要求满足带出去的任意两个同学至少满足下面4条中的一条。(1)身高差大于40(2)性别相同(3)喜欢的音乐属于不同类型(4)喜欢的体育比赛相同(他们有可能是不同队伍的球迷,能聊得不愉快)。挑选尽量多的学生,使得任意两个同学满足上述条件中的一条。
——————————————————————
分男女:
/**
独立集:由一个图两两互不相邻的结点组成。
最大独立集:选择尽量多的结点,使得任意两个结点不相邻(即任意一条边的两个端点不会同时被选中)。
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=550;
bool G[MAXV][MAXV],vis[MAXV];
int match[MAXV];
int n,hei[MAXV];
char sex[MAXV][150],mus_sty[MAXV][150],sport[MAXV][150];
int fabs(int x)
{
return x>=0?x:-x;
}
bool find_AP(int u){
for(int i=1; i<=n; i++) { //此处i代表女生,u代表男生
if(strcmp(sex[i],"M")) //判断性别,选择女生
if(G[u][i]&&!vis[i]){
vis[i]=true;
if(!match[i]||find_AP(match[i])){
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int ans=0;
scanf("%d",&n);
memset(G,0,sizeof(G));
memset(match,0,sizeof(match));
for(int i=1; i<=n; i++){
scanf("%d%s%s%s",&hei[i],sex[i],mus_sty[i],sport[i]);
}
bool is_sex,is_m_s,is_sp;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
is_sex=strcmp(sex[i],sex[j]); //性别是否相同
is_m_s=strcmp(mus_sty[i],mus_sty[j]); //喜欢的音乐风格是否相同
is_sp=strcmp(sport[i],sport[j]); //喜爱的运动是否相同
if(fabs(hei[i]-hei[j])<=40&&is_sex&&(!is_m_s)&&is_sp){
if(!strcmp(sex[i],"M")) //过滤掉i为女生的情况
G[i][j]=true; //建图,性别分离,i代表男性j代表女性
}
}
}
for(int i=1; i<=n; i++){
memset(vis,0,sizeof(vis));
if(!strcmp(sex[i],"M")) //由男生开始增广
if(find_AP(i))
ans++;
}
printf("%d\n",n-ans);
}
return 0;
}
不分男女
——————————————————————
/**
独立集:由一个图两两互不相邻的结点组成。
最大独立集:选择尽量多的结点,使得任意两个结点不相邻(即任意一条边的两个端点不会同时被选中)。
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=550;
bool G[MAXV][MAXV],vis[MAXV];
int match[MAXV];
int n,hei[MAXV];
char sex[MAXV][150],mus_sty[MAXV][150],sport[MAXV][150];
int fabs(int x)
{
return x>=0?x:-x;
}
bool find_AP(int u){
for(int i=1; i<=n; i++) {
if(G[u][i]&&!vis[i]){
vis[i]=true;
if(!match[i]||find_AP(match[i])){
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int ans=0;
scanf("%d",&n);
memset(G,0,sizeof(G));
memset(match,0,sizeof(match));
for(int i=1; i<=n; i++){
scanf("%d%s%s%s",&hei[i],sex[i],mus_sty[i],sport[i]);
}
bool is_sex,is_m_s,is_sp;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
is_sex=strcmp(sex[i],sex[j]); //性别是否相同
is_m_s=strcmp(mus_sty[i],mus_sty[j]); //喜欢的音乐风格是否相同
is_sp=strcmp(sport[i],sport[j]); //喜爱的运动是否相同
if(fabs(hei[i]-hei[j])<=40&&is_sex&&(!is_m_s)&&is_sp){
G[i][j]=true; //建图
G[j][i]=true;
}
}
}
for(int i=1; i<=n; i++){
memset(vis,0,sizeof(vis));
if(find_AP(i))
ans++;
}
printf("%d\n",n-ans/2);
}
return 0;
}