填志愿(计蒜客第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 }

 

posted @ 2015-08-27 10:13  冷夏的博客园  阅读(399)  评论(3编辑  收藏  举报