简单二分匹配,检查是否能完全匹配。这里面的代码并不很好,有改善空间。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector>
 4 using namespace std;
 5 const int N = 310;
 6 int P[N],C[N],n,m;
 7 bool vis[N];
 8 vector <int> next[N];
 9 bool SearchPath(int u)
10 {
11     int i;
12     for(i = 0; i < next[u].size(); i++)
13     if(!vis[next[u][i]])
14     {
15         vis[next[u][i]] = true;
16         if(C[next[u][i]] == -1 || SearchPath(C[next[u][i]]))
17         {
18             C[next[u][i]] = u; P[u] = next[u][i];
19             return true ;
20         }
21     }
22     return false ;
23 }
24 int MaxMatch()
25 {
26     int u, cnt = 0 ;
27     memset(P, -1, sizeof(P));
28     memset(C, -1, sizeof(C));
29     for(u = 1; u <= n; u++)
30     if(P[u] == -1)
31     {
32         memset(vis, 0, sizeof(vis));
33         if(SearchPath(u)) cnt++;
34     }
35     return cnt;
36 }
37 int main()
38 {
39     int T,i,j,t1,t2;
40     scanf("%d",&T);
41     while(T--)
42     {
43         scanf("%d%d",&n,&m);
44         for(i = 1; i <= n; i++)
45         {
46             scanf("%d",&t1);
47             for(j = 0; j < t1; j++)
48             {
49                 scanf("%d",&t2);
50                 next[i].push_back(t2);
51             }
52         }
53         if(MaxMatch() != n)
54             printf("NO\n");
55         else printf("YES\n");
56         for(i = 1; i <= n; i++)
57             next[i].clear();
58     }
59     return 0;
60 }