Guardian of Decency
Description
Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is afraid that some of them might become couples. While you can never exclude this possibility, he has made some rules that he thinks indicates a low probability two persons will become a couple:
So, for any two persons that he brings on the excursion, they must satisfy at least one of the requirements above. Help him find the maximum number of persons he can take, given their vital information.
- Their height differs by more than 40 cm.
- They are of the same sex.
- Their preferred music style is different.
- Their favourite sport is the same (they are likely to be fans of different teams and that would result in fighting).
So, for any two persons that he brings on the excursion, they must satisfy at least one of the requirements above. Help him find the maximum number of persons he can take, given their vital information.
Input
The first line of the input consists of an integer T ≤ 100 giving the number of test cases. The first line of each test case consists of an integer N ≤ 500 giving the number of pupils. Next there will be one line for each pupil consisting of four space-separated data items:
No string in the input will contain more than 100 characters, nor will any string contain any whitespace.
- an integer h giving the height in cm;
- a character 'F' for female or 'M' for male;
- a string describing the preferred music style;
- a string with the name of the favourite sport.
No string in the input will contain more than 100 characters, nor will any string contain any whitespace.
Output
For each test case in the input there should be one line with an integer giving the maximum number of eligible pupils.
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
Northwestern Europe 2005
题意:带出去的任意两个学生至少满足下面4条中的一条.
(1)身高相差大于40厘米
(2)性别相同。
(3)最喜欢的音乐属于不同类型
(4)最喜欢的体育比赛相同
你的任务是挑选尽量多的学生,使得任意两个学生至少满足上述条件中的一条。
输入:T组数据,n个学生:身高、性别、音乐风格、体育比赛
分析:本题的模型是二分图的最大独立集,即选择尽量多的结点,使得任意两个结点不相邻。最大独立集=结点总数-最大匹配数
覆盖集:对于每条边,至少有一个点要被选中。
独立集:对于每条边,至少有一个点不被选中。(由一个图的两两互不相邻的一些节点组成的集合称为该图的一个独立集.)
最大独立集:图G的含结点最多的独立集称为最大独立集.
建模方法:将每个人看做一个结点,如果两个人4个条件都不满足,就意味着他们不能同时被选择,连一条无向边。因为每个人不是男生就是女生,所以这个图就是二分图。
代码1:将所有人进行搜索,得出来的最大匹配是ans的两倍
代码2:对女生进行搜索,找与其相连的男生。poj和hdu好像不支持fabs,要用abs,而codeblocks要用fabs,可以自己写函数。。。
题意:带出去的任意两个学生至少满足下面4条中的一条.
(1)身高相差大于40厘米
(2)性别相同。
(3)最喜欢的音乐属于不同类型
(4)最喜欢的体育比赛相同
你的任务是挑选尽量多的学生,使得任意两个学生至少满足上述条件中的一条。
输入:T组数据,n个学生:身高、性别、音乐风格、体育比赛
分析:本题的模型是二分图的最大独立集,即选择尽量多的结点,使得任意两个结点不相邻。最大独立集=结点总数-最大匹配数
覆盖集:对于每条边,至少有一个点要被选中。
独立集:对于每条边,至少有一个点不被选中。(由一个图的两两互不相邻的一些节点组成的集合称为该图的一个独立集.)
最大独立集:图G的含结点最多的独立集称为最大独立集.
建模方法:将每个人看做一个结点,如果两个人4个条件都不满足,就意味着他们不能同时被选择,连一条无向边。因为每个人不是男生就是女生,所以这个图就是二分图。
代码1:将所有人进行搜索,得出来的最大匹配是ans的两倍
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int N;
int h[505];//身高
char X[505][2]; //性别
char mu[505][105];//音乐
char ga[505][105];//体育比赛
bool map[505][505],visit[505];
int match[505];
bool dfs(int u)
{
int i;
for(i=1;i<=N;i++)
{
if(map[u][i]&&!visit[i])
{
visit[i]=true;
if(!match[i]||dfs(match[i]))
{
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
int T,i,j,ans;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d",&N);
memset(mu,'\0',sizeof(mu));
memset(ga,'\0',sizeof(ga));
memset(X,'\0',sizeof(X));
for(i=1;i<=N;i++)
{
cin>>h[i]>>X[i]>>mu[i]>>ga[i];
}
memset(map,false,sizeof(map));
memset(match,0,sizeof(match));
for(i=1;i<=N;i++)
{
for(j=i+1;j<=N;j++)
{
if(abs(h[i]-h[j])<=40&&strcmp(X[i],X[j])&&strcmp(mu[i],mu[j])==0&&strcmp(ga[i],ga[j]))
{
map[i][j]=true;
map[j][i]=true;
}
}
}
for(i=1;i<=N;i++)
{
memset(visit,false,sizeof(visit));
if(dfs(i))
ans++;
}
printf("%d\n",N-ans/2);
}
return 0;
}
代码2:对女生进行搜索,找与其相连的男生。poj和hdu好像不支持fabs,要用abs,而codeblocks要用fabs,可以自己写函数。。。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int N;
int h[505];//身高
char X[505][2]; //性别
char mu[505][105];//音乐
char ga[505][105];//体育比赛
bool map[505][505],visit[505];
int match[505];
bool dfs(int u)
{
int i;
for(i=1;i<=N;i++)
{
if(strcmp(X[i],"F"))
if(map[u][i]&&!visit[i])
{
visit[i]=true;
if(!match[i]||dfs(match[i]))
{
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
int T,i,j,ans;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d",&N);
memset(mu,'\0',sizeof(mu));
memset(ga,'\0',sizeof(ga));
memset(X,'\0',sizeof(X));
for(i=1;i<=N;i++)
{
cin>>h[i]>>X[i]>>mu[i]>>ga[i];
}
memset(map,false,sizeof(map));
memset(match,0,sizeof(match));
for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
if(abs(h[i]-h[j])<=40&&strcmp(X[i],X[j])&&strcmp(mu[i],mu[j])==0&&strcmp(ga[i],ga[j]))
{
if(!strcmp(X[i],"F"))
map[i][j]=true;
}
}
}
for(i=1;i<=N;i++)
{
memset(visit,false,sizeof(visit));
if(!strcmp(X[i],"F"))
if(dfs(i))
ans++;
}
printf("%d\n",N-ans);
}
return 0;
}