Sweety

Practice makes perfect

导航

POJ 2458 Kindergarten( 最大独立集(图) & 完全子图 )

Posted on 2014-11-01 13:24  蓝空  阅读(1415)  评论(0编辑  收藏  举报

 

打开题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2458

 

本题其实就是在求最大独立子图(最大完全数)(注意在这个算法里没有将最大独立子图所包含的元素求出来)(也就是说现在最大独立子图还不会求...  

 

解题思路:

本题应该是在匈牙利算法上的一个小的变式,这道题的难点在于转化,题目要求的是一个集合,集合中的任意两个顶点之间都有连线,求出全部都联通的最大数,但是二部图中并没有专门相关的方法解决这个问题.

然而,通过合理的转化,这个问题也就变成了二部图范畴内的问题:

一般的建图方式是u和v认识,就在u和v之间连一条边,但是这道题要反过来做,彼此不认识就连一条边,这么一来求出二部图的最大独立集就是答案,因为独立集内部所有顶点之间没有连线,也就是互相认识,而且是这个独立集是最大的.

 

 

下面补充几个(下面的这几个概念对本体来说很重要,关于二分图的概念参考网址

二分图又称作二部图

独立集:任意两点都不相连的顶点的集合

独立数:独立集中顶点的个数//完全子图:任意两点都相连的顶点的集合

完全子图:任意两点都相连的顶点的集合

最大完全数:最大完全子图中顶点的个数

最大完全数=原图的补图的最大独立数

最大独立数=总的顶点数-最大匹配数(这里不是)

本题是要求图中的最大完全子图(最大团)中顶点的个数。

由于原图的补图是一个二分图,其最大完全数等价于其补图的最大独立集中元素的个数,

于是可以根据二分图的性质求出这个最大独立集。而普通图的最大团则是一个NP问题。

定理:二分图最大独立集=顶点数-二分图最大匹配(匈牙利算法)

最大完全数:图中最大完全子图的顶点个数。

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

 

上这几个概念有点乱,但是得好好想想。。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000;
int girl, boy ;        // u, v数目,要初始化!!!
bool g[MAXN][MAXN];       // g[i][j] 表示xi与yj相连
int  match[MAXN];      // 记录男生是否匹配以及匹配情况
bool check[MAXN];   // 辅助量检查某轮match[i]是否被check

bool SearchPath(int u){   //匈牙利算法
	int v;
    for(v = 0; v < boy; v++)
		if( g[u][v] && !check[v])
		{
			check[v] = true;
			if( match[v] == -1 || SearchPath( match[v] ))
			{
				match[v] = u;
                return true ;
            }
        }
		return false ;
}

int main()
{
	int m,i,a,b,cnt=0,j;
	while (   scanf("%d%d%d", &girl, &boy, &m)  &&   (girl||boy||m)  )
	{
		cnt++;  //计数
		memset(g,1,sizeof(g));
		while(m--)  //标记
		{
			scanf("%d%d",&a,&b);
			g[a-1][b-1]=false; //认识的人没有边
		}
		int u, count = 0 ;
		memset( match, -1, sizeof(match) );
		for( u = 0; u < girl; u++ )
		{
			memset(check, 0, sizeof (check));
			if(SearchPath(u))
				count++;
		}
		printf("Case %d: ",cnt);
		printf("%d\n",girl+boy-count);
	}
}


 


有木有感觉和匈牙利算法很像。。。