标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 21382 | Accepted: 8408 |
Description
Input
Output
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
题目大意
N个学生,p们课,每一门课程可以有多个学生选修,给出每门课程学生的选修情况,问:对于每门课程可不可以找到一个课代表( 前提是该学生要选修该门课程,每个课程都有一个不同的课代表)
输入:
输入有多组数据:
每组数据的第一行包含两个由空格隔开的两个正整数:P(1 < = P < = 100)课程数量和N(1 < = 300)学生人数。
以下P行描述从课程1到课程P:第一个数是选修人数Ci,后面Ci个学生编号。
输出:YES 或 NO
总之就是二分图的最大匹配问题
匈牙利算法走起(hangarian)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn=305; 8 const int maxm=60005; 9 int Head[105],Next[maxm],Adj[maxm]; 10 int match[maxn]; 11 bool use[maxn]; 12 int c,N,P,cnt; 13 14 void AddEdge(int u,int v) 15 { 16 c++; 17 Adj[c]=v; 18 Next[c]=Head[u]; 19 Head[u]=c; 20 } 21 22 bool dfs(int x) 23 { 24 for(int i=Head[x];i;i=Next[i]) 25 { 26 int v=Adj[i]-100; 27 if(use[v]) continue; 28 use[v]=true; 29 if(match[v]==0||dfs(match[v])) 30 { 31 match[v]=x; 32 return true; 33 } 34 } 35 return false; 36 } 37 38 void hangarian() 39 { 40 memset(match,0,sizeof(match)); 41 for(int i=1;i<=P;i++) 42 { 43 memset(use,false,sizeof(use)); 44 if(dfs(i)) cnt++; 45 } 46 } 47 48 int main() 49 { 50 int t; 51 cin>>t; 52 while(t--) 53 { 54 cin>>P>>N; 55 int m,v; 56 cnt=c=0; 57 memset(Head,0,sizeof(Head)); 58 memset(Next,0,sizeof(Next)); 59 memset(Adj,0,sizeof(Adj)); 60 for(int i=1;i<=P;i++) 61 { 62 scanf("%d",&m); 63 while(m--) 64 { 65 scanf("%d",&v); 66 AddEdge(i,v+100); 67 } 68 } 69 hangarian(); 70 if(cnt==P) printf("YES"); 71 else printf("NO"); 72 cout<<endl; 73 } 74 return 0; 75 }
标签:
原文地址:http://www.cnblogs.com/cnblogsLSY/p/5824207.html