对应POJ题目:点击打开链接
1:身高相差40cm(不包括)
2:性别相同
3:音乐品味不同
4:体育爱好相同
有N个人,问最多有多少人,使他们任意两人之间都不能结婚。
思路:明显就是图的最大独立集了,想办法化为二分图,即是按性别划分,男一边,女一边,然后能结婚的就从男那边连一条线到女那边。那同一边的肯定不会有连线,满足二分图。故ans = N -最大匹配。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#define ms(x,y) memset(x,y,sizeof(x))
#define ABS(x) ((x)>0?(x):-(x))
const int MAXN=500+10;
const int INF=1<<30;
using namespace std;
int bn,gn;
int link[MAXN];
int vis[MAXN];
int net[MAXN][MAXN];
struct People
{
int h;
char sex[3],music[105],sport[105];
}boy[MAXN],girl[MAXN];
int dfs(int u)
{
for(int v=0; v<gn; v++){
if(!vis[v] && net[u][v]){
vis[v] = 1;
if(link[v] == -1 || dfs(link[v])){
link[v] = u;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int res = 0;
ms(link, -1);
for(int u=0; u<bn; u++){
ms(vis, 0);
if(dfs(u)) res++;
}
return res;
}
int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
ms(net,0);
bn = 0;
gn = 0;
int n;
scanf("%d", &n);
People p;
for(int i=0; i<n; i++){
scanf("%d%s%s%s", &p.h, p.sex, p.music, p.sport);
if(p.sex[0] == 'F') boy[bn++] = p;
else girl[gn++] = p;
}
for(int i=0; i<bn; i++){
for(int j=0; j<gn; j++){
if(ABS(boy[i].h - girl[j].h) <= 40 && !strcmp(boy[i].music, girl[j].music) && strcmp(boy[i].sport,girl[j].sport))
net[i][j] = 1;
}
}
printf("%d\n", n - MaxMatch());
}
return 0;
}