题意:有n个人,给出每个人的身高,性别,喜欢的音乐和运动,组成一个集合要求集合内任意两个人满足下面4个不可能成为夫妻的条件之一,问集合人数最多是多少。
1.两个人身高差大于40。
2.性别不同(呵呵哒)。
3.喜欢的音乐不一样。
4.喜欢的运动一样。
题解:是一个算二分图的最大独立集的题,先把人分成两个没有交集的集合,男人和女人,然后剩下三个条件全部不满足,解 = n - 最大匹配数。
#include <stdio.h>
#include <cmath>
#include <string.h>
#include <vector>
using namespace std;
const int N = 505;
struct Peo {
int h;
char pre[105], spo[105];
}f[N], m[N];
int n, vis[N], link[N];
vector<int> g[N];
bool judge(int a, int b) {
if (fabs(m[a].h - f[b].h) <= 40 && strcmp(m[a].pre, f[b].pre) == 0 && strcmp(m[a].spo, f[b].spo) != 0)
return true;
return false;
}
bool dfs(int u) {
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (!vis[v]) {
vis[v] = 1;
if (link[v] == -1 || dfs(link[v])) {
link[v] = u;
return true;
}
}
}
return false;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
char s[5];
int a, n1 = 0, n2 = 0;
for (int i = 0; i < n; i++) {
scanf("%d%s", &a, s);
if (s[0] == 'M') {
m[n1].h = a;
scanf("%s%s", m[n1].pre, m[n1].spo);
n1++;
}
else {
f[n2].h = a;
scanf("%s%s", f[n2].pre, f[n2].spo);
n2++;
}
}
for (int i = 0; i < n1; i++) {
g[i].clear();
for (int j = 0; j < n2; j++)
if (judge(i, j))
g[i].push_back(j);
}
memset(link, -1, sizeof(link));
int res = 0;
for (int i = 0; i < n1; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i))
res++;
}
printf("%d\n", n - res);
}
return 0;
}