标签:
这题的题意大概是说: 需要选一个学生集合,这个集合满足: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\n",ans); 57 if( ans == p) 58 printf("YES\n"); 59 else 60 printf("NO\n"); 61 } 62 }
有一个小优化,就是当p大于n,直接输出NO; 421MS/256MS的差距;
标签:
原文地址:http://www.cnblogs.com/xiaoniuniu/p/4395674.html