题目:梦幻大PK

题目描述

难得到了生日,正逢上班里面一年一度的梦幻大PK,分2组对拼。但是由于某种原因,参加PK的第1组中有些人不能和第2组人PK。可能是因为等级、互克、相生等关系。于是,南瓜(为鄙班中队长 and 团支书)想要确定最多要多少次PK。十分惋惜,因为鄙人的大名在学校大黑板上挂了2个月(就是全国1=而已拉)了。于是就来 found 鄙人。但是鄙人正准备着自己的生日,于是只好把这个难题交付各位OIers了。十分遗憾,南瓜小姐的统计上有点问题,使问题变的复杂了点。(2组人数相同)

输入格式

第1行,一个数,N。
接下来N行,其中第i行第1个数M,表示第1组第i个人不能和第2组的M个人PK。然后M个数,表示第1组第i个人与第2组哪M个人不能PK。(注:这M个数或许会有重复)。
数据范围:0<=M<N<=1000。其他输入的数不超过1000。

输出格式

一个数,表示最多能举行多少场PK。

 

 

题解:

用匈牙利算法,第一次哦,要加深理解

代码实现:

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

 

posted on 2012-01-30 10:55  怡红公子  阅读(297)  评论(0编辑  收藏  举报