Description
n个同学,一些男女同学会有缘分成为情侣,格式ni:(m) n1 n2 n3表示同学ni有缘与n1,n2,n3成为情侣,求集合中不存在有缘成为情侣的同学的最大同学数
Input
多组输入,每组用例第一行为同学人数n,之后n行第i行表示第i-1名同学的缘分情况,输入格式ni:(m) n1 n2 n3表示同学ni有缘与n1,n2,n3成为情侣,以文件尾结束输入
Output
对于每组用例,输出集合中不存在有缘成为情侣的同学的最大同学数
Sample Input
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
Sample Output
5
2
Solution
最大点独立集裸题,最大独立点集=总点数n-最大匹配数,注意此题是n个点内部匹配,所以每种匹配都会有重复,hungary算法的结果需除以2才是最大匹配数,即ans=n-hungary( )/2
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 555
int uN,vN; //u,v数目
int g[maxn][maxn];//编号是0~n-1的
int linker[maxn];
bool used[maxn];
bool dfs(int u)
{
int v;
for(v=0;v<vN;v++)
if(g[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
return false;
}
int hungary()
{
int res=0;
int u;
memset(linker,-1,sizeof(linker));
for(u=0;u<uN;u++)
{
memset(used,0,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(g,0,sizeof(g));//初始化
uN=vN=n;
for(int i=0;i<n;i++)
{
int x,y,k;
scanf("%d: (%d) ",&x,&k);
while(k--)
{
scanf("%d",&y);
g[x][y]=1;
}
}
printf("%d\n",n-hungary()/2);
}
return 0;
}