当前位置: 移动技术网 > IT编程>网页制作>Html5 > POJ 3692 Kindergarten(挑战程序设计竞赛,二分图最大团)

POJ 3692 Kindergarten(挑战程序设计竞赛,二分图最大团)

2020年07月15日  | 移动技术网IT编程  | 我要评论

挑战程序设计竞赛,283页,二分图最大团
题目意思:
幼儿园,所有女生相互之间认识,所有男生之间相互认识,有些女生和某些男生认识。
现在,老师想挑选一些孩子玩游戏,这需要所有玩家彼此认识。您将帮助查找老师可以挑选的最大孩子数。

本题要点:
1、二分图的团:
二分图的子图中,左部的任意一个节点和右部所有的节点都有连线,该子图称为二分图的 团。
点数最多的团,称为二分图的最大团。
2、二分图G 的补图 G1, G的最大团等于其补图G1的最大独立集。
3、二分图的最大独立集 = 二分图的总点数 - 二分图的最大匹配数
绕到最后,还是用 增广路算法,求二分图的最大匹配数.

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MaxN = 210;
int a[MaxN][MaxN], match[MaxN];
bool vis[MaxN];
int g, b, m;
int complementary[MaxN][MaxN];	//补图

bool dfs(int x)
{
	for(int y = 1; y <= b; ++y)
	{
		if(!complementary[x][y] || vis[y])
			continue;
		vis[y] = true;
		if(!match[y] || dfs(match[y]))
		{
			match[y] = x;
			return true;
		}
	}
	return false;
}

int main()
{
	int cnt = 0, x, y;
	while(scanf("%d%d%d", &g, &b, &m) != EOF)
	{
		if(0 == g && 0 == b && 0 == m)
			break;
		memset(a, 0, sizeof a);
		memset(match, 0, sizeof match);
		memset(complementary, 0, sizeof complementary);
		while(m--)
		{
			scanf("%d%d", &x, &y);
			a[x][y] = 1;
		}
		for(int i = 1; i <= g; ++i)
		{
			for(int j = 1; j <= b; ++j)
			{
				if(!a[i][j])
				{
					complementary[i][j] = 1;
				}
			}
		}
		int ans = 0;
		for(int i = 1; i <= g; ++i)
		{
			memset(vis, 0, sizeof vis);
			if(dfs(i))
				++ans;
		}
		printf("Case %d: %d\n", ++cnt, g + b - ans);
	}
	return 0;
}

/*
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
*/

/*
Case 1: 3
Case 2: 4
*/

本文地址:https://blog.csdn.net/qq_38232157/article/details/107337801

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网