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 }