HDU

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1083

http://poj.org/problem?id=1469

题意:给你P个课程,并且给出每个课程的学生,求出学生与课程的最大匹配数目,问结果是否与课程数目相同,相同输出YES,否则NO

分析:匈牙利算法

1.每个学生选的都是不同的课(即不能有两个学生选同一门课)

2.每门课都有一个代表(即P门课都被成功选过)

求解二部图的最大匹配。只要匹配可以盖住每门课程,即匹配数与课程数量相等,委员会就可以组成。

Sample Input
2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1
 

Sample Output
YES
NO 

AC代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<queue>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<iostream>
 8 
 9 using namespace std;
10 typedef long long LL;
11 
12 #define INF 0x3f3f3f3f
13 #define N 420
14 #define MAXN 100000000
15 #define mod 1000000007
16 
17 int maps[N][N],n,p,v[N],vis[N];///vis[i]表示y集合中的点是否匹配;
18 
19 int Hungary(int s)
20 {
21     int i;
22     for(i=1;i<=p;i++)
23         if(v[i]==0&&maps[s][i]==1)
24     {
25         v[i]=1;
26         if(vis[i]==0||Hungary(vis[i])==1)
27         {
28             vis[i]=s;
29             return 1;
30         }
31     }
32     return 0;
33 }
34 
35 int main()
36 {
37     int T,m,i,j,x;
38 
39     scanf("%d", &T);
40 
41     while(T--)
42     {
43         memset(vis,0,sizeof(vis));
44         memset(maps,0,sizeof(maps));
45 
46         scanf("%d %d", &p,&n);
47 
48         for(i=1;i<=p;i++)
49         {
50             scanf("%d",&m);
51 
52             for(j=1;j<=m;j++)
53             {
54                 scanf("%d", &x);
55                 maps[x][i]=1;
56             }
57         }
58         int ans=0;
59         for(i=1;i<=n;i++)///
60         {
61             memset(v,0,sizeof(v));
62             if(Hungary(i))
63                 ans++;
64         }
65         if(ans==p)
66             printf("YES
");
67         else
68             printf("NO
");
69     }
70     return 0;
71 }
原文地址:https://www.cnblogs.com/weiyuan/p/5740134.html