填志愿(计蒜客第50题)
有一个国家采取全民教育、自主选择的方式,尽可能多的将高中毕业的学生安排进大学进行学习(国家只会安排学生进入他们希望进入的大学,而不会让他们进入自己不想去的学校)。但是,在此之前,所有的高中毕业生,需要先填写自己希望进入的大学的报考编号,我们称之为——填志愿。但是最终每个学生只能被其中一所大学录取。请你帮助计算今年在这个国家,最多能有多少个高中毕业学生进入大学学习。
输入格式:
第1行包括两个整数,N和M,分别表示今年高中毕业生的数量与今年招生的大学的数量(0≤N,M≤200)。
输入第2行-输入第N+1行,每行对应一个毕业生今年填写的志愿,每行第一个数字表示学生填写的想去的大学的总数S,后面S个数分别为这些大学的报考编号(每行的数字都由空格分隔,0≤S≤M)。
输出格式:
第一行输出一个整数,表示在满足学生零个或一个填报志愿进行录取的情况下,国家最多可以安排多少将高中毕业的学生安排进大学进行学习。
很明显一个二分图匹配问题,单用网络流也能搞
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int MAXN=1000; 5 int uN,vN; //u,v数目 6 int g[MAXN][MAXN];//编号是0~n-1的 7 int linker[MAXN]; 8 bool used[MAXN]; 9 bool dfs(int u) 10 { 11 int v; 12 for(v=1;v<=vN;v++) 13 if(g[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 int n,m; 39 while(cin>>n>>m) 40 {uN=n;vN=m; 41 int x,y; 42 for(int i=1;i<=n;i++) 43 { 44 cin>>x; 45 while(x--) 46 { 47 cin>>y; 48 g[i][y]=1; 49 } 50 } 51 52 cout<<hungary()<<endl; 53 54 } 55 56 return 0; 57 58 }