大学的第二年,有人开始研究学生之间的浪漫关系。“恋爱关系”是指一个女孩和一个男孩之间的关系。由于研究的原因,有必要找出满足这一条件的最大集合:没有两名学生曾“恋爱”过。这个项目的结果是这样一组学生的数量。
输入包含几个文本格式的数据集。每个数据集代表研究的一组主题,并说明如下:
学生人数
每个学生的描述,格式如下
student_identifier:(number_of_romantic_relations)学生标识1学生标识2学生标识3.
或
学生标识符:(0)
学生标识符是n个科目的0到n-1之间的整数.
对于每个给定的数据集,程序应该将包含结果的一行写入标准输出。
学校对n个学生(男女都有)进行的调查了,发现了某些学生暗生情愫,现在需要你选出一个最大的集合,这个集合内部没有两个人暗生情愫.学生的编号是0~n-1
输入
输入包含多组数据
第一行一个整数n,表示学生的数量.
接下来n行,第一个数表示一个学生编号,接下来一个数表示与他产生联系的人的数量,接下来是一组编号表示产生联系的学生编号.具体格式见样例.
你可以认为,数据是对称的,且不会出现奇环.
输出量
对于每组测试数据,输出一个整数,表示最多可以选出的人数.
样本输入
7
0: (3) 4 5 6
1: (2) 4 6
2: (0)
3: (0)
4: (2) 0 1
5: (1) 0
6: (2) 0 1
3
0: (2) 1 2
1: (1) 0
2: (1) 0
样本输出
5
2
输入没有指明那些是男孩/女孩。所以要拆点,把
i 拆成 i 跟 i’ 分别放入X、Y,原先U = V - M,所以 2U = 2V - 2M。 分析:
故U = n - M'/2。
代码:
#include<stdio.h>
#include<string.h>
#define N 1010
int map[N][N],mode[N],vis[N];
int t;
int find(int x)//寻找增广路! 找到返回1,否则返回0!
{
int i,j;
for(i=0;i<t;i++)
{
if(map[x][i]&&!vis[i])//与x相连点,并且没有遍历到
{
vis[i]=1;//标记为遍历过
if(!mode[i]||find(mode[i]))//i 点 没有和另一部分匹配或 和i配对的点 没有匹配!
{
mode[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
while(scanf("%d",&t)!=EOF)
{
int i,j;
memset(map,0,sizeof(map));
memset(mode,0,sizeof(mode));
for(i=0;i<t;i++)
{
int tt,x,y;
scanf("%d: (%d)",&x,&tt);
while(tt--)
{
scanf("%d",&y);
map[x][y]=1;//标记为通路
}
}
int s=0;
for(i=0;i<t;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))//增广路
{
s++;
}
}
printf("%d\n",t-s/2);
}
return 0;
}