最大独立集( Kindergarten hdu 3692)

最大独立集=节点数-最大匹配数;


匹配数的求解方式在上一篇博客当中,如果在阅读本博文有什么不懂得地方也可以先看看上一篇博文对于匈牙利算法的解释上篇博文链接:https://mp.csdn.net/postedit/99627466

在求解最大独立数时最重要的还是求解最大匹配数,毕竟结点数都是知道的相加一下就能非常轻松地得到了,而求解最大匹配数的方法在上一篇博客里面已经介绍过了。但我发现两者之中有着细微的差别,于是我将区别写在这里。上次的最大匹配数是找自己认识的人组成最大匹配数,但是最大独立集就是去掉那些相互之间不认识的,使的在这个群体里面的人都是相互认识的,所以我发现这里的最大匹配数匹配时要找不认识的人匹配,然后减去这些人剩下的就都是认识的了。

所以代码上面也是有着细微的差别;

原代码:

		if(vis[i]==0 && map[x][i])

更改后:

		if(vis[i]==0 && !map[x][i])

接下来是刚刚碰到的问题及AC代码

In a kindergarten, there are a lot of kids. All girls of the kids know each other and all boys also know each other. In addition to that, some girls and boys know each other. Now the teachers want to pick some kids to play a game, which need that all players know each other. You are to help to find maximum number of kids the teacher can pick.

Input

The input consists of multiple test cases. Each test case starts with a line containing three integers
G, B (1 ≤ G, B ≤ 200) and M (0 ≤ M ≤ G × B), which is the number of girls, the number of boys and
the number of pairs of girl and boy who know each other, respectively.
Each of the following M lines contains two integers X and Y (1 ≤ X≤ G,1 ≤ Y ≤ B), which indicates that girl X and boy Y know each other.
The girls are numbered from 1 to G and the boys are numbered from 1 to B.

The last test case is followed by a line containing three zeros.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the maximum number of kids the teacher can pick.

Sample Input

2 3 3
1 1
1 2
2 3
2 3 5
1 1
1 2
2 1
2 2
2 3
0 0 0

Sample Output

Case 1: 3
Case 2: 4

题意描述:有若干个男生和若干个女生,给出一定数量的条件,判断男女生是否认识;老师需要从小孩中找到最多的小孩彼此     认识的数量达到最大

解题思路:先假设所有人都被选中,然后找到男女生不认识彼此的人,用人数减去彼此不认识的组合数得到的就是最大可挑选的 人数;

AC代码:

#include<stdio.h>
#include<string.h>
int match[1001];
int vis[1001];
int map[505][505];
int m;
int find(int x)
{
	int i,j,k;
	for(i=1;i<=m;i++)
	{
		if(vis[i]==0 && !map[x][i])
		{
			vis[i]=1;
			if(match[i]==-1 || find(match[i]))
			{
				match[i]=x;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int n,i,j,k,a,b,sum,t=1;
	while(scanf("%d%d%d",&n,&m,&k)!=EOF)
	{
		sum=0;
		if(m==0 && k==0 && n==0)
		break;
		memset(map,0,sizeof(map));
		memset(match,-1,sizeof(match));
		for(i=0;i<k;i++)
		{
			scanf("%d%d",&a,&b);
			map[a][b]=1;
		}
		for(i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis));
			if(find(i))
			sum++;
		}
		printf("Case %d: %d\n",t++,m+n-sum);
	}
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/weixin_44584292/article/details/99638473