poj 2771 Guardian of Decency

题意:教授带学生出去玩,学生们两两一组,为防他们萌生爱意,教授想出了几个十分蛋疼分组办法,(这里我必须要吐槽下。。)满足一个便不会相爱。

1  身高大于40cm    (对不起,你太矮了,咱两不合适,多么正当的拒绝理由。。。)

2    相同性别     (题目一定是出的比较早,否则绝对不会这样想。。。)

3    爱好不同     (文科生和理科生注定无法相爱。。。)

4  喜欢的运动相同,因为他们会因为喜欢的体育明星不同而撕逼,无法相爱(这个理由我也是醉了。。。)

思路  建图的话要反着建, 把不符合上面所有条件的即可以相爱的连在一起,然后 求出最大独立集=n-最大匹配数

最大独立集: 图中任意两个顶点都不相连的顶点集合。

#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
struct Note
{
	int h;
	char a[3];
	char b[100];
	char c[100];
}note[600];
bool used[600];
int g[600][600];
int linker[600];
int n;
int vn,un;
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 ab(int x)
{
    return x<0?-x:x;
}
int main()
{
   // freopen("in.txt","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		vn=un=n;
		for(int i=0;i<n;i++)
		{
			scanf("%d%s%s%s",¬e[i].h,¬e[i].a,¬e[i].b,¬e[i].c);
		}
		memset(g,0,sizeof(g));
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(ab(note[i].h-note[j].h)<=40&¬e[i].a[0]!=note[j].a[0]
					&&strcmp(note[i].b,note[j].b)==0&&strcmp(note[i].c,note[j].c)!=0)
				{
					g[i][j]=g[j][i]=1;
				}
			}
		}
		int ans=n-hungary()/2; // 这里除以二是因为建图的时候将人数看成了两倍
		printf("%d\n",ans);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值