hdu1068解题报告--Girls and Boys--可以说是白话最大独立集学习总结

一开始做题,我就以为是单纯的最大匹配,还觉得案例是不是有错,后来才知道这是一个叫什么“最大独立集”的东东,因为第一次接触,于是到处百度,到后来发现概念还是很模糊。。囧。。。。下面先通俗的解释一下“最大独立集”,(很形象生动。。有助理解,不要看了文字就烦就不想看大笑)相信会对第一次接触“最大独立集”的人有帮助

一如往常,个人觉得在看一个知识概念之前,先粗略的了解一下这是个什么东东,然后再去看概念会比较好,结合题目来看,题目求的是“romantically involved”(后面解释为“浪漫组合”).每个人都有自己想与之一起学习的人,有的有多个,有的有0个,那么会有多少个这样的“浪漫组合”,我最开始的解决就是用0~N个人去和0~N个人匹配,那么得到的结果除以2就是结果(因为如果0想和7一起,匹配一次,那么7也会和0匹配一次,但是总共只有N个人,就相当于只组合成了一对“浪漫组合”),后面发现输出的答案都和案例输出不同....其实,原因是这样的,在其中的一些人组成“浪漫组合"之后,剩下的那些人就只能自己和自己”浪漫“啦大笑.....比如案例中的7个人组合了2对,我们就可以看做他们组成两个独立的集合(两个”浪漫组合“),也就是剩下三个人互相不能组成,就各自单独为一个独立的集合(也就是”浪漫组合“),那么总共就有5个“浪漫组合”、也就是5个独立集。。。。相信到这里大概知道最大独立集这个看似深奥的东东的本质了吧

那么现在根据公式  最大独立集=顶点数-最大匹配 (这个结合刚刚的分析不可能不懂大笑)说白了就是很裸的匈牙利模板算法,直接给出代码

/*
注意理解最大独立集
*///2484MS 4152K 
#include<stdio.h>
#include<string.h>

#define MAX 1001

int N;
int map[MAX][MAX];
int link[MAX];
bool useif[MAX];

void init()
{
	int st,m,to;
	memset(map,0,sizeof(map));
	for(int i=0;i<N;i++)
	{
		scanf("%d: (%d)",&st,&m);
		while(m--)
		{
			scanf("%d",&to);
			map[st][to]=1;
		}
	}
}

bool can(int t)
{
	for(int i=0;i<N;i++)
	{
		if(!useif[i] && map[t][i])
		{
			useif[i]=true;
			if(link[i]==-1 || can(link[i]))
			{
				link[i]=t;return true;
			}
		}
	}
	return false;
}

int match()
{
	int sum=0;
	memset(link,-1,sizeof(link));
	for(int i=0;i<N;i++)
	{
		memset(useif,false,sizeof(useif));
		if(can(i))
			sum++;
	}
	return sum;
}

int main()
{
	while(~scanf("%d",&N))
	{
		init();
		printf("%d\n",N-(match()+1)/2);//注意这里....匹配的时候返回的次数多了一半
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值