題解:根據性別建立二分圖,把可能相愛的異性匹配在一起,題目意思是找儘量多的點,使得其中任意2點之間沒有邊,即尋找二分圖的最大獨立集,最大獨立集 = 點數 - 最大匹配數(最小點覆蓋數),所以直接匈牙利算法找最大匹配數即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 510;
const int maxc = 110;
struct Node {
int height;
char gender[3];
char music[maxc];
char sport[maxc];
} stu[maxn];
int n;
int G[maxn][maxn];
bool mark[maxn];
int match[maxn];
bool KM(int u) {
for(int v = 0;v < n;v++) {
if(G[u][v] == 0) continue;
if(stu[v].gender[0]!='F') continue;
if(mark[v]) continue;
mark[v] = 1;
if(match[v]==-1||KM(match[v])) {
match[v] = u;
return true;
}
}
return false;
}
int main() {
// freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--) {
memset(match,-1,sizeof(match));
scanf("%d",&n);
for(int i = 0;i < n;i++) {
scanf("%d%s%s%s",&stu[i].height,stu[i].gender,stu[i].music,stu[i].sport);
}
memset(G,0,sizeof(G));
for(int i = 0;i < n;i++)
for(int j = i+1;j < n;j++) {
if((strcmp(stu[i].gender,stu[j].gender)!=0))
if((abs(stu[i].height-stu[j].height)<=40)
&& (strcmp(stu[i].music,stu[j].music)==0)
&& (strcmp(stu[i].sport,stu[j].sport)!=0 )) {
G[i][j] = G[j][i] = 1;
}
}
int ans = 0;
for(int i = 0;i < n;i++) {
memset(mark,0,sizeof(mark));
if(strcmp(stu[i].gender,"M") == 0)
if(KM(i)) ans++;
}
printf("%d\n",n-ans);
}
return 0;
}