Courses HDU - 1083

原题链接

考察:二分图匹配

上题学会如何分配集合,这题又学会哪个作为匹配的主动方...

正常思路是人到课,但是本题课到人更方便处理,猜想二分图应该是一对多做主动方

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 300010,M = 310;
 6 int h[M],match[M],idx;
 7 bool st[M];
 8 struct Road{
 9     int from,to,ne;
10 }road[N];
11 void add(int a,int b)
12 {
13     road[idx].from = a,road[idx].to = b,road[idx].ne = h[a],h[a] = idx++;
14 }
15 void inits()
16 {
17     memset(h,-1,sizeof h); idx = 0;
18     memset(match,0,sizeof match);
19 }
20 bool findw(int x)
21 {
22     for(int i=h[x];i!=-1;i=road[i].ne)
23     {
24         int j = road[i].to;
25         if(st[j]) continue;
26         st[j] = 1;
27         if(!match[j]||findw(match[j]))
28         {
29             match[j] = x;
30             return true;
31         }
32     }
33     return false;
34 }
35 int main()
36 {
37 //    freopen("in.txt","r",stdin);
38     int T;
39     scanf("%d",&T);
40     while(T--)
41     {
42         inits();
43         int m,n,ans = 0;
44         scanf("%d%d",&m,&n);
45         for(int i=1;i<=m;i++)
46         {
47             int k; scanf("%d",&k);
48             for(int j=1;j<=k;j++) 
49             {
50                 int y; scanf("%d",&y);
51                 add(i,y);
52             }
53         }
54         for(int i=1;i<=m;i++)
55         {
56             memset(st,0,sizeof st);
57             if(findw(i)) ans++;
58         }
59         if(ans==m) puts("YES");
60         else puts("NO");
61     }
62     return 0;
63 }

 

posted @ 2021-01-23 14:50  acmloser  阅读(39)  评论(0编辑  收藏  举报