#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 305;
int uN, vN;
bool g[MAXN][MAXN];
int xM[MAXN], yM[MAXN];
bool chk[MAXN];
bool searchPath(int u)
{
	for(int v = 0; v < vN; v++)
		if(g[u][v] && !chk[v])
		{
			chk[v] = true;
			if(yM[v] == -1 || searchPath(yM[v]))
			{
				yM[v] = u;
				xM[u] = v;
				return true;
			}
		}
	return false;
}

int maxMatch()
{
	int u, ret = 0;
	memset(xM, -1, sizeof(xM));
	memset(yM, -1, sizeof(yM));
	for(u = 0; u < uN; u++)
		if(xM[u] == -1)
		{
			memset(chk, false, sizeof(chk));
			if(searchPath(u))ret++;
		}
	return ret;
}
int main()
{
	int icase;
	scanf("%d", &icase);
	while(icase--)
	{
		//矩阵一定要初始化 
		memset(g, 0, sizeof(g));
		int p, n;
		scanf("%d%d", &p, &n);
		uN = p;
		vN = n;
		int cnt, j;
		for(int i = 0; i < p; i++)
		{
			scanf("%d", &cnt);
			while(cnt--)
			{
				scanf("%d", &j);
				//转换为下标从0开始 
				j--;
				g[i][j] = true;
			}
		}
		//每一个课程都只有一个代表 
		if(maxMatch() == p)puts("YES");
		else puts("NO");
	}
	system("pause");
	return 0;
}

  

posted on 2012-05-04 00:21  猿类的进化史  阅读(188)  评论(0编辑  收藏  举报