题意:教授带学生出去玩,学生们两两一组,为防他们萌生爱意,教授想出了几个十分蛋疼分组办法,(这里我必须要吐槽下。。)满足一个便不会相爱。
1 身高大于40cm (对不起,你太矮了,咱两不合适,多么正当的拒绝理由。。。)
2 相同性别 (题目一定是出的比较早,否则绝对不会这样想。。。)
3 爱好不同 (文科生和理科生注定无法相爱。。。)
4 喜欢的运动相同,因为他们会因为喜欢的体育明星不同而撕逼,无法相爱(这个理由我也是醉了。。。)
思路 建图的话要反着建, 把不符合上面所有条件的即可以相爱的连在一起,然后 求出最大独立集=n-最大匹配数
最大独立集: 图中任意两个顶点都不相连的顶点集合。
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
struct Note
{
int h;
char a[3];
char b[100];
char c[100];
}note[600];
bool used[600];
int g[600][600];
int linker[600];
int n;
int vn,un;
bool dfs(int u)
{
int v;
for(v=0;v<vn;v++)
{
if(g[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for( u=0;u<un;u++)
{
memset(used,0,sizeof(used));
if(dfs(u))
res++;
}
return res;
}
int ab(int x)
{
return x<0?-x:x;
}
int main()
{
// freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
vn=un=n;
for(int i=0;i<n;i++)
{
scanf("%d%s%s%s",¬e[i].h,¬e[i].a,¬e[i].b,¬e[i].c);
}
memset(g,0,sizeof(g));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(ab(note[i].h-note[j].h)<=40&¬e[i].a[0]!=note[j].a[0]
&&strcmp(note[i].b,note[j].b)==0&&strcmp(note[i].c,note[j].c)!=0)
{
g[i][j]=g[j][i]=1;
}
}
}
int ans=n-hungary()/2; // 这里除以二是因为建图的时候将人数看成了两倍
printf("%d\n",ans);
}
}