hdu 1083 Courses

这题的题意大概是说: 需要选一个学生集合,这个集合满足:1.每个学生仅能代表一门学科  2.每门学科都需要一名学生来代表 ; 求是否存在这样的一个集合;

一个完备匹配 .也是简单的模板题..算出最大匹配,若其值与课程数量相同,则输出YES,否则输出NO;

 1 #include <iostream>
 2 #include <string.h>
 3 using namespace std;
 4 const int MAXN=510;
 5 int uN,vN;//u,v数目
 6 int map[MAXN][MAXN];
 7 int linker[MAXN];
 8 bool used[MAXN];
 9 bool dfs(int u)//从左边开始找增广路径
10 {
11     int v;
12     for(v=1;v<=vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
13         if(map[u][v]&&!used[v])
14         {
15             used[v]=true;
16             if(linker[v]==-1||dfs(linker[v]))
17             {//找增广路,反向
18                 linker[v]=u;
19                 return true;
20             }
21         }
22         return false;//这个不要忘了,经常忘记这句
23 }
24 int hungary()
25 {
26     int res=0;
27     int u;
28     memset(linker,-1,sizeof(linker));
29     for(u=1;u<=uN;u++)
30     {
31         memset(used,0,sizeof(used));
32         if(dfs(u)) res++;
33     }
34     return res;
35 }
36 int main()
37 {
38     //freopen("1083.txt","r",stdin);
39     int T,n,p,t,u;
40     scanf("%d",&T);
41     while(T--)
42     {
43         scanf("%d %d",&p,&n);
44         uN = p ; vN = n;
45         memset(map,false,sizeof(map));
46         for(int i = 1 ;i <= p ; i++)
47         {
48             scanf("%d",&t);
49             while(t--)
50             {
51                 scanf("%d",&u);
52                 map[i][u] = 1;
53             }
54         }
55         int ans = hungary();
56         //printf("%d
",ans);
57         if( ans == p)
58             printf("YES
");
59         else 
60             printf("NO
");
61     }
62 }
View Code

 有一个小优化,就是当p大于n,直接输出NO; 421MS/256MS的差距;

原文地址:https://www.cnblogs.com/xiaoniuniu/p/4395674.html