hdu 3829 Cat VS Dog(最大独立集)

题目描述:动物园有N只猫,M只狗,P个小孩。每个小孩都有自己喜欢的动物和讨厌的动物,如果他喜欢狗,那么就讨厌猫,
如果他讨厌猫,那么他就喜欢狗。某个小孩能开心,当且仅当他喜欢的动物留在动物园和讨厌的动物不在动物园里面。
现让管理员通过带走某些动物,问最多能使多少个孩子开心。
解题思路:题目有一个关键点,孩子喜欢猫,必然不喜欢狗,反之。 即猫和猫之间,狗和狗之间一定不存在矛盾关系,符合二分图的概念。
如何建立二分图:
若甲小孩喜欢的动物与乙小孩讨厌的动物一样,或者甲小孩讨厌的动物与乙小孩喜欢的动物一样,那甲乙之间就存在着排斥关系,则他们之间连接一条边。

建立完二分图之后,相当于求二分图的最大独立集 = 顶点数 - 最大匹配数。

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;

const int MAXN = 508;

struct Child
{
	string like;
	string dis;
};

Child cat[MAXN],dog[MAXN];
int map[MAXN][MAXN];
int link[MAXN];
int used[MAXN];
int cat_num;
int dog_num;

int dfs(int k)
{
	for(int i=0; i<dog_num; i++)
	{
		if(!used[i] && map[k][i])
		{
			used[i] = 1;
			if(link[i] == -1 || dfs(link[i]))
			{
				link[i] = k;
				return 1;
			}
		}
	}
	return 0;
}

int maxMatch()
{
	int cnt = 0;
	for(int i=0; i<cat_num; i++)
	{
		memset(used,0,sizeof(used));
		if(dfs(i))
		{
			cnt++;
		}
	}
	return cnt;
}

int main()
{
	int n,m,p;

	string a,b;
	while(cin>>n>>m>>p)
	{
		memset(map,0,sizeof(map));
		memset(link,-1,sizeof(link));
		cat_num = dog_num = 0;
		while(p--)
		{
			cin>>a>>b;
			//将喜欢猫的孩子划为A子集
			if(a[0] == 'C') 
			{
				cat[cat_num].like = a;
				cat[cat_num].dis = b;
				cat_num++;
			}
			//将喜欢狗的孩子划为B子集
			if(a[0] == 'D')
			{
				dog[dog_num].like = a;
				dog[dog_num].dis = b;
				dog_num++;
			}
		}
		for(int i=0; i<cat_num; i++)
		{
			for(int j=0; j<dog_num; j++)
			{
				//若存在排斥关系
				if(cat[i].like == dog[j].dis || cat[i].dis == dog[j].like)
				{
					map[i][j] = 1;
				}
			}
		}
		int cnt = maxMatch();
		//最大独立集 = 顶点数 - 最大匹配数
		cout<<cat_num+dog_num-cnt<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值