HDU 1083 Courses(最大匹配)

题目地址:点击打开链接

思路:二分图的最大匹配,代码的解释是照着并查集详解的内容写的,思路差不多,并查集详解地址:

AC代码:

#include<stdio.h>
#include<string.h>
int lol[101][301],visit[301],cf[301],n;
bool find(int l)
{
	int i;
	for(i=1; i<=n; i++)
	{
		if(lol[l][i] && !visit[i])//有好感并且没尝试把妹子许配给别人,要是visit[i]等于1表明,前面有一个人要i这个妹子要定了
		{
			visit[i] = 1;//表明i这个妹子l要定了,别人不能再娶了,不然下面一条语句腾妹子的过程,本来想让i这个妹子的丈夫重娶一个妹子,结果这个妹子的丈夫还是娶了她,然后又把这个妹子配给l,这就太扯淡了,所以这一句不能放在if语句里面,如果最终妹子i还是和他丈夫生活在一起,没有被拆分,对最终结果也没有影响,也省得再给妹子的丈夫重找媳妇,因为根本不可能
			if(!cf[i] || find(cf[i]))//i这个妹子没丈夫或者能让她的丈夫重娶一个妹子,和这个妹子离婚
			{
				cf[i] = l;//妹子i的丈夫就是l了
				return true;//光棍l摆脱单身
			}
		}
	}
	return false;
}
int main()
{
	int t,p,i,j,sum,a,sum1;
	scanf("%d",&t);
	while(t--)
	{
		memset(lol,0,sizeof(lol));
		memset(cf,0,sizeof(cf));
		sum1 = 0;
		scanf("%d%d",&p,&n);
		for(i=1; i<=p; i++)
		{
			scanf("%d",&sum);
			for(j=0; j<sum; j++)
			{
				scanf("%d",&a);
				lol[i][a] = 1;
			}
		}
		for(i=1; i<=p; i++)
		{
			memset(visit,0,sizeof(visit));//visit每尝试一次就得把visit清零一次
			if(find(i))
				sum1++;
		}
		if(p == sum1)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}


你可能感兴趣的:(HDU 1083 Courses(最大匹配))