二分图最大匹配。用匈牙利算法可以轻松解决。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int link[50];
bool gl[50][50];
int n,m;
bool vis[50];
bool Match(int v)
{
for(int i=1; i<=n; ++i)
if(!vis[i]&&gl[v][i])
{
vis[i]=true;
if(!link[i]||Match(link[i]))
{
link[i]=v;
return true;
}
}
return false;
}
int Convers(char *x)
{
if(!strcmp(x,"XXL")) return 1;
else if(!strcmp(x,"XL")) return 2;
else if(!strcmp(x,"L")) return 3;
else if(!strcmp(x,"M")) return 4;
else if(!strcmp(x,"S")) return 5;
else if(!strcmp(x,"XS")) return 6;
}
void AddEdge(int v,int u,int N)
{
for(int i=1; i<=N; ++i)
gl[v][(u-1)*N+i]=true;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
int N=n/6;
memset(link,0,sizeof(link));
memset(gl,0,sizeof(gl));
for(int i=1; i<=m; ++i)
{
char a[5],b[5];
scanf("%s%s",a,b);
AddEdge(i,Convers(a),N);
AddEdge(i,Convers(b),N);
}
int cnt=0;
for(int i=1; i<=m; ++i)
{
memset(vis,0,sizeof(vis));
if(Match(i))
cnt++;
}
if(cnt==m) puts("YES");
else puts("NO");
}
return 0;
}