题意:老师要带一些人出去,要求这里面任何两个人之间不会萌生爱意
思路:有某种关系的人相互连边,很明显就是求最大独立集,而这里只有男生女生两种,故这是二分图匹配问题,因为二分图中,最大独立集 + 最小顶点覆盖 = 顶点数
直接套匈牙利算法模板就行
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
const int maxn = 510;
using namespace std;
vector<int> G[maxn];
int from[maxn], use[maxn];
int n, T;
string music[maxn], sport[maxn];
char sex[maxn][5];
int height[maxn];
void init() {
memset(from, -1, sizeof(from));
for(int i = 0; i < maxn; i++)
G[i].clear();
}
int match(int x) {
for(int i = 0; i < G[x].size(); i++) {
int v = G[x][i];
if(use[v]) continue; use[v] = 1;
if(from[v] == -1 || match(from[v])) {
from[v] = x;
return 1;
}
}
return 0;
}
int maxp() {
int sum = 0;
for(int i = 0; i < n; i++) {
memset(use, 0, sizeof(use));
sum += match(i);
}
return sum;
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
init();
for(int i = 0; i < n; i++) {
scanf("%d %s", &height[i], sex[i]);
cin >> music[i] >> sport[i];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(abs(height[i] - height[j]) > 40) continue;
if(sex[i][0] == sex[j][0]) continue;
if(music[i] != music[j]) continue;
if(sport[i] == sport[j]) continue;
G[i].push_back(j);
}
}
int ans = maxp();
printf("%d\n", (2 * n - ans) / 2);
}
return 0;
}