//类型:二分匹配中的最大独立子集
//公式:二分图最大独立集点数等于顶点总数减去最大匹配数(|M|);
//技巧:此题不进行顶点的划分(将所有学生作为左集合中的顶点和右集合中的顶点),将所有顶点进行匹配,最后除以2即可
#include <stdio.h>
#include <string.h>
//#include <conio.h>
#define arraysize 501
int map[arraysize][arraysize];
bool final[arraysize];
int match[arraysize];
int n;
bool DFS(int p)
{
int i,j;
int temp;
for(i=0;i<n;++i)
{
if(map[p][i] && !final[i])
{
final[i]= true;
temp = match[i];
match[i] = p;
if(temp==0 || DFS(temp)) return true;
match[i] = temp;
}
}
return false;
}
int mat()
{
int i,j;
int maxmatch = 0;
for(i=0;i<n;++i)
{
memset(final,0,sizeof(final));
if(DFS(i)) maxmatch++;
}
return maxmatch;
}
int main()
{
//freopen("1.txt","r",stdin);
int i,j;
while(scanf("%d",&n)!=EOF)
{
int count;
int temp;
memset(map,0,sizeof(map));
memset(match,0,sizeof(match));
//此处涉及字符串的处理操作
for(i=0;i<n;++i)
{
scanf("%d",&temp); //scanf读取除字符(%c)类型的数据时都会忽略到开头的空白字符和回车,此处相当于两个getchar,但使用两个getchar()超时
getchar(); //吃掉冒号
getchar(); //吃掉空格
getchar(); //吃掉左括弧
scanf("%d",&count);
getchar(); //吃掉右括弧
for(j=0;j<count;++j)
{
scanf("%d",&temp);
map[i][temp] = 1;
}
}
printf("%d\n",n-mat()/2); //输出最大独立子集数
}
//getch();
return 0;
}
对于输入可以采取以下方式:
scanf("%d",&temp); //scanf读取除字符(%c)类型的数据时都会忽略到开头的空白字符和回车,此处相当于两个getchar,但使用两个getchar()超时
getchar(); //吃掉冒号
getchar(); //吃掉空格
scanf("(%d)",&count);
/*
scanf("%d",&temp); //scanf读取除字符(%c)类型的数据时都会忽略到开头的空白字符和回车,此处相当于两个getchar,但使用两个getchar()超时
getchar(); //吃掉冒号
scanf(" (%d)",&count); //使用scanf吃掉空格
*/