简单二分图。另外鄙视自己花了这么长时间。 #include <stdio.h> #include <string.h> struct person{ long h; char sex,music[102],sport[102]; }p[501]; long n,ptrm[501],ptrf[501],tm,tf,/*g[501][501],*/mat[501]; bool vis[501]; long abs(long x) { return x<0?-x:x; } bool check(long x,long y) { return abs(p[x].h-p[y].h)<=40&&(!strcmp(p[x].music,p[y].music))&&strcmp(p[x].sport,p[y].sport); } bool hung(long v) { for(long i=1;i<=tm;++i) { if((!vis[i])&&check(ptrf[v],ptrm[i])) { vis[i]=true; if((!mat[i])||hung(mat[i])) { mat[i]=v; return true; } } } return false; } void work() { //memset(g,0,sizeof(g)); tm=tf=0; scanf("%d/n",&n); for(long i=1;i<=n;++i) scanf("%d %c %s %s/n",&p[i].h,&p[i].sex,p[i].music,p[i].sport); for(long i=1;i<=n;++i) if(p[i].sex=='F')ptrf[++tf]=i; else ptrm[++tm]=i; // for(long i=1;i<=tf;++i) // for(long j=1;j<=tm;++j) // g[i][j]=g[j][i]=check(ptrf[i],ptrm[j]); long ans=0; memset(mat,0,sizeof(mat)); for(long i=1;i<=tf;++i) { memset(vis,0,sizeof(vis)); if(hung(i))++ans; } printf("%d/n",n-ans); } int main() { freopen("p2771.in","r",stdin); freopen("p2771.out","w",stdout); long casen; scanf("%d",&casen); for(long i=0;i<casen;++i) work(); return 0; }