题目:门票系统

题目描述

2008年,第31届魁地奇世界杯即将举行。全世界巫师热情高涨,争相订购魁地奇世界杯门票。但门票的总数是有限的,所以魁地奇世界杯举办方将不得不拒绝一部分人的订票请求。为了公平,魁地奇世界杯举办方决定,每个订票者最多只能获得1张门票。而很多人不只订了1张门票,
假设每个人在比赛中预订了1张门票。现在你要做的就是替魁地奇世界杯举办方开发一个订票处理系统,以满足可能多的订票请求。(只要获取1张门票就视为满足请求,每场比赛只有一张票)

输入格式

第一行2个整数,分别是订票人数 n(n<=100)和比赛场数m(m<=300)
第二行至(n+2)行,行首一个整数pi,表示预订门票张数,其后pi个数,分别是预定订场次的编号。

输出格式

只有一行,包含一个整数,即最多满足订票请求的人数

题解:

匈牙利算法,第一次用。解释一下,之所以用一个use[],是为了避免find(f[j])的门票也为j,use[j]赋值为1后,说明一定有人拥有了它,对find(k)无影响.

代码实现:

View Code
 1 #include<iostream>
2 using namespace std;
3
4 int map[101][301]={0},f[301]={0},n,m,ans=0;bool g[101][301]={0},use[301];
5
6 bool find(int k){
7 int i,j;
8 for(i=1;i<=map[k][0];i++)
9 {
10 j=map[k][i];
11 if(use[j]==0)
12 {
13 use[j]=1;
14 if(f[j]==0||find(f[j]))
15 {f[j]=k;return 1;}
16 }
17 }
18 return 0;
19 }
20
21 int main()
22 {
23 int i,j,k;
24 scanf("%d %d",&n,&m);
25 for(i=1;i<=n;i++)
26 {
27 int p;
28 scanf("%d",&p);
29 for(j=1;j<=p;j++)
30 {scanf("%d",&k);g[i][k]=1;}
31 }
32
33 for(i=1;i<=n;i++)
34 for(j=1;j<=m;j++)
35 if(g[i][j]==1) {map[i][0]++;map[i][map[i][0]]=j;}
36
37 for(i=1;i<=n;i++)
38 {
39 memset(use,0,sizeof(use));
40 if(find(i))
41 ans++;
42 }
43
44
45 cout<<ans<<endl;
46 return 0;
47
48 }
原文地址:https://www.cnblogs.com/noip/p/2331697.html