这个题有两种做法,可以一开始就换成两种点集,一种男生一种女生,然后匹配的时候就跑出来那个最大的,用总共的减去那个最大的就可以,
这种做法当时没有想起来,建边的时候直接两个都建边,跑全部的,最后的最大匹配除以2,因为男生和女生都可以当匹配点所以,就最后的结果除以2就可以
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <math.h>
#include <stack>
#include <utility>
#include <string>
#include <sstream>
#include <cstdlib>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 500 + 10;
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
bool vis[maxn];
int mark[maxn];
int link[maxn];
int g[maxn][maxn];
int n;
struct people
{
int h;
char sex;
string mc;
string sp;
} pe[maxn];
bool judge(int x,int i)
{
if(abs(pe[x].h - pe[i].h) > 40 || (pe[x].sex == pe[i].sex) || (pe[x].mc != pe[i].mc) || pe[x].sp == pe[i].sp)
return false;
return true;
}
bool find1(int x)
{
for(int i = 0; i < n; i++)
{
if(!mark[i]&& g[x][i])
{
mark[i] = 1;
if((!link[i] || find1(link[i])))
{
link[i] = x;
return 1;
}
}
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(g,0,sizeof(g));
memset(link,0,sizeof(link));
for(int i = 0; i < n; i++)
cin>>pe[i].h>>pe[i].sex>>pe[i].mc>>pe[i].sp;
int ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
if(judge(i,j))
g[i][j] = g[j][i] = 1;
}
}
for(int i = 0; i < n; i++)
{
memset(mark,0,sizeof(mark));
if(find1(i))
ans++;
}
printf("%d\n",n - ans / 2);
}
return 0;
}
也贴一下另一种做法
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 500+5;
struct PP {
int h;
char music[111],sport[111];
}boy[maxn], girl[maxn], tmp;
int n, m, match[maxn];
bool vis[maxn], mp[maxn][maxn];
bool dfs(int i) {
for(int j = 1;j <= m; j++) if(mp[i][j] && !vis[j]) {
vis[j] = 1;
if(!match[j] || dfs(match[j])) {
match[j] = i;
return true;
}
}
return false;
}
char sex[2], music[111], sport[111];
int main() {
int t, i, j;
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
int n1 = 0, n2 = 0, h;
for(i = 1;i <= n; i++) {
scanf("%d%s%s%s", &tmp.h, sex, tmp.music, tmp.sport);
if(sex[0] == 'M') boy[++n1] = tmp;
else girl[++n2] = tmp;
}
n = n1, m = n2;
for(i = 1;i <= n; i++) {
for(j = 1;j <= m; j++) {
if(abs(boy[i].h - girl[j].h) <= 40 && strcmp(boy[i].music, girl[j].music) == 0 && strcmp(boy[i].sport, girl[j].sport) != 0) {
mp[i][j] = 1;
}
else
mp[i][j] = 0;
}
}
for(i = 1;i <= m; i++) match[i] = 0;
int ans = 0;
for(i = 1;i <= n; i++) {
for(j = 1;j <= m; j++) vis[j] = 0;
if(dfs(i)) ans++;
}
printf("%d\n", n+m-ans);
}
return 0;
}